资讯中心

Docker容器技术从入门到实践:核心概念、安装部署与生产环境指南

📅 2026/8/17 15:07:14
Docker容器技术从入门到实践:核心概念、安装部署与生产环境指南
1. 项目概述为什么Docker是开发现代应用的基石如果你在开发、测试或者运维的岗位上待过一段时间大概率听过或者用过Docker。它早已不是几年前那个需要向人费力解释的“新潮玩具”而是成为了现代软件开发和部署流程中一个绕不开的基础设施。我最早接触Docker时它解决了我一个最头疼的问题环境不一致。开发时在本机跑得好好的服务一到测试服务器就各种报错不是依赖库版本不对就是系统配置有差异。Docker用一个“集装箱”的概念把应用及其所有依赖打包成一个标准化的镜像从根本上解决了“在我机器上能跑”的世纪难题。简单来说Docker是一个开源的应用容器引擎。你可以把它想象成一个超级轻量级的虚拟机但它比虚拟机更高效、启动更快、资源占用更少。它允许你将应用打包成一个可移植的、自包含的单元这个单元可以在任何安装了Docker引擎的计算机上以完全相同的方式运行。无论是CentOS、Ubuntu还是macOS、Windows只要镜像构建好运行结果就是一致的。这对于团队协作、持续集成和自动化部署来说价值巨大。这篇内容的目标就是为你提供一份从零开始覆盖Docker安装、核心概念理解、日常使用到进阶技巧的完整指南。无论你是刚入门的新手想在自己的电脑上搭个环境学学Python或Node.js还是有一定经验的开发者希望将现有项目容器化或者运维同学需要管理成百上千的容器这里面的内容都能给你提供直接的参考和“抄作业”的步骤。我会尽量避开那些晦涩的理论用实际操作和踩过的坑来告诉你怎么把Docker真正用起来。2. Docker核心概念扫盲镜像、容器与仓库在动手安装和敲命令之前花几分钟搞清楚Docker最核心的三个概念非常有必要。这能帮你理解后续所有操作背后的逻辑而不是死记硬背命令。2.1 镜像应用的“模板”与“只读光盘”你可以把Docker镜像理解为一个只读的模板。这个模板里包含了运行某个软件所需的一切代码、运行时环境、系统工具、系统库以及设置。它本身是静止的、不可改变的。比如一个nginx:latest镜像就包含了运行Nginx Web服务器所需的所有文件。镜像采用分层存储的结构。这是什么意思呢假设你基于一个最精简的Ubuntu系统镜像安装了一个Python环境然后又把你的代码拷贝进去。Docker不会生成一个全新的、巨大的文件而是会记录每一层的变化。Ubuntu基础层、Python安装层、你的代码层每一层都是只读的。这种设计带来了巨大的好处资源共享和快速分发。如果你拉取另一个也基于Ubuntu的镜像那么Ubuntu这一层已经在本地了无需重复下载节省时间和磁盘空间。2.2 容器镜像的运行实例容器是镜像的一个运行实例。当你执行docker run命令时Docker引擎会基于指定的镜像创建一个可写的容器层通常称为“容器层”或“读写层”然后在其上启动进程。这个容器层是临时的。你对运行中的容器所做的任何修改比如创建新文件、修改配置、安装新软件都只存在于这个容器层。一旦你删除容器这个可写层也会被一并删除镜像本身保持不变。这就像你从光盘镜像启动了一台电脑容器你在电脑里做的所有操作都不会影响原来的光盘。这种特性使得容器具有极致的轻量性和一致性——每次从同一个镜像启动的容器初始状态都是一模一样的。2.3 仓库镜像的“App Store”仓库是集中存放镜像的地方最著名的公共仓库是Docker Hub你可以把它类比为手机的应用商店。在这里你可以找到几乎所有主流软件和服务的官方镜像如MySQL、Redis、Nginx、Python等。你也可以创建自己的私有仓库用于存放团队内部构建的镜像。仓库里又分为多个“货架”这就是Registry。一个Registry里可以包含多个Repository每个Repository可以包含多个Tag。通常一个Repository对应一个软件如nginx而Tag则用来区分这个软件的不同版本如latest,1.21,alpine。alpine是一个特别需要注意的标签它表示这个镜像基于超轻量级的Alpine Linux系统构建体积非常小是生产环境的首选。理解了这三者的关系整个Docker的工作流就清晰了从仓库拉取镜像 - 基于镜像创建并运行容器 - 在容器中运行你的应用。3. 全平台Docker安装与初始化配置详解安装Docker是第一步但不同操作系统下的安装方式和可能遇到的坑截然不同。我会分别针对Linux、macOS和Windows给出最稳妥的安装方案并重点解决那些高频出现的错误。3.1 Linux系统安装以Ubuntu/CentOS为例在Linux服务器上我们通常使用命令行安装Docker Engine。这是最纯粹、最常用的方式。对于Ubuntu/Debian系系统首先更新软件包索引并安装一些必要的工具sudo apt-get update sudo apt-get install ca-certificates curl gnupg lsb-release接着添加Docker的官方GPG密钥和软件源sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null注意上面命令中的$(lsb_release -cs)会自动获取你的Ubuntu版本代号如jammy、focal。确保Docker支持你的系统版本。对于某些国内服务器如果访问官方源速度慢可以考虑使用国内镜像源但务必注意镜像源的安全性和时效性。最后安装Docker引擎sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin对于CentOS/RHEL系系统首先安装yum-utils包并设置稳定的仓库sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo然后安装Docker引擎sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin安装后的关键操作启动Docker服务并设置开机自启sudo systemctl start docker sudo systemctl enable docker验证安装运行经典的hello-world镜像。sudo docker run hello-world如果看到欢迎信息说明安装成功。强烈建议将当前用户加入docker组默认情况下执行docker命令需要sudo权限。为了避免每次输入密码可以将你的用户加入docker组。sudo usermod -aG docker $USER执行此命令后你需要完全退出当前终端会话并重新登录或者新开一个终端窗口用户组变更才会生效。之后你就可以直接使用docker命令而无需sudo了。3.2 macOS与Windows安装Docker Desktop的抉择对于macOS和Windows用户官方提供了集成的Docker Desktop。它不仅仅是一个Docker引擎还包含了图形化管理界面、Kubernetes集群等工具对初学者非常友好。macOS安装访问Docker官网下载适用于Apple芯片M1/M2/M3或Intel芯片的Docker Desktop.dmg安装包。双击打开将Docker图标拖拽到Applications文件夹。在应用程序中启动Docker Desktop。首次启动需要权限确认并可能要求你输入系统密码。启动后你会在菜单栏看到鲸鱼图标。打开终端就可以直接使用docker和docker-compose命令了。Windows安装 Windows安装相对复杂一些因为它严重依赖操作系统的虚拟化功能。前提条件检查至关重要Windows版本必须是Windows 10/11 64位的专业版、企业版或教育版。家庭版需要额外步骤启用Hyper-V且可能不稳定。开启虚拟化进入BIOS/UEFI设置确保CPU的虚拟化技术Intel VT-x或AMD-V已启用。开启Hyper-V和容器功能在“控制面板 - 程序和功能 - 启用或关闭Windows功能”中勾选“Hyper-V”和“容器”。重启电脑。安装Docker Desktop从官网下载Docker Desktop Installer.exe。运行安装程序按照提示操作。安装过程中建议勾选“使用WSL 2而不是Hyper-V”如果你使用的是Windows 10 2004以上版本或Windows 11。WSL 2后端性能更好资源占用更少与Windows文件系统的互操作性也更佳。处理启动失败问题 如果你遇到类似“Docker Desktop failed to start because virtualisation support wasn’t detected”的错误请按以下步骤排查确认BIOS虚拟化已开启使用任务管理器CtrlShiftEsc在“性能”标签页查看“虚拟化”是否已启用。关闭冲突的虚拟化软件某些安全软件、安卓模拟器如蓝叠或旧版本的VMware/VirtualBox可能会占用虚拟化功能。尝试暂时关闭或卸载它们。以管理员身份运行右键点击Docker Desktop图标选择“以管理员身份运行”。重置Docker Desktop在系统托盘右键点击Docker图标选择“Troubleshoot - Reset to factory defaults”。注意这会删除所有镜像、容器和卷。3.3 初始化配置镜像加速与守护进程调优安装完成后有两项配置能极大提升使用体验。配置国内镜像加速器 从Docker Hub拉取镜像在国内速度可能较慢。我们可以配置一个镜像加速器地址。对于Linux系统编辑或创建/etc/docker/daemon.json文件{ registry-mirrors: [ https://docker.mirrors.ustc.edu.cn, https://hub-mirror.c.163.com, https://mirror.baidubce.com ] }你可以选择其中一个或多个地址。保存后重启Docker服务生效sudo systemctl restart docker对于Docker DesktopmacOS/Windows可以通过图形界面配置点击系统托盘Docker图标 -Settings或Preferences-Docker Engine在JSON配置中添加registry-mirrors项然后点击Apply Restart。调整Docker守护进程配置 默认的磁盘空间、日志驱动等配置可能不适合生产环境。我们可以通过修改daemon.json进行优化。{ log-driver: json-file, log-opts: { max-size: 10m, max-file: 3 }, data-root: /path/to/your/custom/docker-data }log-driver和log-opts将容器日志限制为每个文件最大10MB最多保留3个文件防止日志撑爆磁盘。>docker search nginx这会列出Docker Hub上所有包含nginx关键词的镜像。通常我们直接拉取官方镜像。docker pull nginx:latest # 或者拉取特定版本 docker pull nginx:1.21-alpine # 如果不指定标签默认拉取 latest docker pull nginxpull命令会下载镜像的所有分层到本地。查看本地镜像docker images # 或者更详细的格式 docker image ls这个命令会列出本地所有镜像显示仓库名、标签、镜像ID、创建时间和大小。删除本地镜像 当镜像不再需要时可以删除以释放空间。删除前必须确保没有容器依赖此镜像即使是已停止的容器。# 通过镜像ID删除 docker rmi image_id # 通过仓库名:标签删除 docker rmi nginx:latest # 强制删除即使有容器引用不推荐 docker rmi -f image_id # 清理所有未被使用的镜像悬空镜像 docker image prune # 清理所有未被容器使用的镜像危险 docker image prune -a4.2 容器生命周期运行、交互、停止与删除运行容器docker run是最核心的命令它结合了pull如果本地没有镜像、create和start的操作。# 最基本运行前台运行一个nginx容器 docker run nginx # 后台运行并指定容器名称 docker run -d --name my_nginx nginx # 映射端口将容器的80端口映射到主机的8080端口 docker run -d --name my_web -p 8080:80 nginx # 现在可以在浏览器访问 http://localhost:8080 # 映射数据卷将主机/host/path目录挂载到容器的/container/path docker run -d -v /host/path:/container/path nginx # 设置环境变量 docker run -d -e MY_ENVvalue nginx # 以交互模式运行一个Ubuntu容器并进入其bash shell docker run -it --name my_ubuntu ubuntu:latest /bin/bash-d后台运行。--name给容器起个名字否则Docker会随机分配一个。-p端口映射格式为主机端口:容器端口。-v数据卷挂载实现主机与容器间的数据持久化和共享。-e设置环境变量。-it-i保持标准输入打开-t分配一个伪终端通常组合使用以进入交互模式。查看容器状态# 查看正在运行的容器 docker ps # 查看所有容器包括已停止的 docker ps -a # 查看容器的详细信息JSON格式 docker inspect container_name_or_id # 查看容器的实时日志 docker logs -f container_name_or_id与运行中的容器交互# 进入一个正在后台运行的容器的bash终端前提是容器内有bash docker exec -it container_name_or_id /bin/bash # 在容器内执行单条命令并退出 docker exec container_name ls /appexec与run的区别在于exec是在已运行的容器内执行新命令而run是创建新容器。停止、启动、重启与删除容器# 停止一个运行中的容器 docker stop container_name_or_id # 启动一个已停止的容器 docker start container_name_or_id # 重启容器 docker restart container_name_or_id # 删除一个已停止的容器 docker rm container_name_or_id # 强制删除一个运行中的容器 docker rm -f container_name_or_id # 删除所有已停止的容器清理空间常用 docker container prune4.3 数据持久化数据卷与绑定挂载容器本身是临时的其可写层随着容器的删除而消失。为了持久化数据如数据库文件、应用程序日志、配置文件我们必须使用数据卷。数据卷由Docker管理存储在主机文件系统的某个区域通常是/var/lib/docker/volumes/下与容器的生命周期独立。# 创建一个命名的数据卷 docker volume create my_volume # 运行容器并使用该数据卷 docker run -d -v my_volume:/app/data nginx # 查看数据卷详情 docker volume inspect my_volume绑定挂载将主机上的一个特定目录或文件直接挂载到容器中。这种方式更直接你完全清楚数据在主机的位置。# 将主机的/home/user/app目录挂载到容器的/app目录 docker run -d -v /home/user/app:/app nginx实操心得对于开发环境我强烈推荐使用绑定挂载。你可以将本地项目代码目录挂载到容器里这样在主机上用IDE修改代码容器内运行的应用能实时生效无需重新构建镜像极大提升开发效率。对于生产环境使用命名数据卷更规范便于Docker统一管理和备份。5. 构建自定义镜像编写你的第一个Dockerfile使用现成的镜像很方便但更多时候我们需要构建包含自己应用的镜像。这就需要用到Dockerfile——一个文本文件里面包含了一系列构建镜像所需的指令。5.1 Dockerfile指令精讲一个典型的Dockerfile结构如下我们以一个简单的Python Flask应用为例# 第一阶段构建阶段 FROM python:3.9-slim AS builder WORKDIR /app COPY requirements.txt . RUN pip install --user -r requirements.txt # 第二阶段运行阶段 FROM python:3.9-slim WORKDIR /app # 从builder阶段复制已安装的依赖 COPY --frombuilder /root/.local /root/.local # 确保脚本能找到用户安装的包 ENV PATH/root/.local/bin:$PATH # 复制应用代码 COPY . . # 声明容器运行时监听的端口 EXPOSE 5000 # 定义容器启动时执行的命令 CMD [python, app.py]我们来拆解关键指令FROM指定基础镜像。这是必须的第一条指令。选择体积小的官方镜像如-slim,-alpine版本是最佳实践。WORKDIR设置工作目录。后续的RUN、COPY、CMD等命令都会在这个目录下执行。COPY将主机文件或目录复制到镜像内。COPY . .表示将构建上下文中的所有文件复制到镜像的/app目录。RUN在构建镜像时执行命令。常用于安装软件包、编译代码等。每条RUN指令都会创建一个新的镜像层为了减少层数通常将多个命令用连接。ENV设置环境变量。这些变量在构建阶段和容器运行时都可用。EXPOSE声明容器打算使用的端口。这只是一个文档性质的说明实际端口映射需要在docker run时用-p参数指定。CMD指定容器启动时默认执行的命令。一个Dockerfile中只能有一条CMD指令。如果docker run后面指定了其他命令则会覆盖CMD。ENTRYPOINT与CMD类似但更难被覆盖。通常用来设置容器的主程序CMD则作为参数传递给ENTRYPOINT。5.2 多阶段构建优化镜像体积的利器注意上面的例子中使用了AS builder。这是一种称为“多阶段构建”的高级技巧。它的核心思想是在第一个阶段builder使用完整的构建环境可能包含编译器、开发工具等完成编译、安装等“重型”操作。然后在第二个阶段使用一个非常精简的运行环境只从第一个阶段复制必要的产物如编译好的二进制文件、安装好的Python包。这样做的好处是最终的镜像只包含运行应用所必需的文件体积可以缩小数倍甚至数十倍。对于Go、Java、C等需要编译的语言效果尤其显著。5.3 构建镜像与最佳实践编写好Dockerfile后在Dockerfile所在目录执行构建命令docker build -t my-flask-app:latest .-t为镜像打标签格式为name:tag。.指定构建上下文路径。Docker客户端会将这个目录下的所有文件打包发送给Docker守护进程。务必注意在.dockerignore文件中忽略不必要的文件如.git,__pycache__,node_modules可以显著加速构建过程和减小镜像体积。构建镜像的最佳实践使用.dockerignore文件像.gitignore一样排除不需要的文件。一个容器只运行一个进程这是微服务架构的核心思想。不要在一个容器里运行Supervisor来管理多个进程。选择合适的基础镜像优先选择官方镜像并选择-alpine或-slim版本以减小体积。合并RUN指令减少镜像层数。# 不好 RUN apt-get update RUN apt-get install -y package-a package-b # 好 RUN apt-get update apt-get install -y \ package-a \ package-b \ rm -rf /var/lib/apt/lists/* # 清理缓存减小层大小将变化频率低的层放在前面Docker使用缓存加速构建。将不常变的指令如安装依赖放在Dockerfile前面将经常变的指令如复制源代码放在后面。6. Docker Compose编排多容器应用的瑞士军刀当你的应用由多个服务组成例如一个Web应用需要Nginx、Python后端、MySQL数据库和Redis缓存使用docker run一个个启动和管理会非常繁琐。Docker Compose应运而生它允许你使用一个YAML文件来定义和运行多个容器。6.1 Compose文件核心语法解析一个基本的docker-compose.yml文件长这样version: 3.8 # 指定Compose文件格式版本 services: # 定义所有服务 web: # 服务名称 build: . # 从当前目录的Dockerfile构建镜像 ports: - 8000:5000 # 端口映射 volumes: - ./app:/app # 绑定挂载用于开发热重载 environment: - FLASK_ENVdevelopment depends_on: # 依赖关系先启动db和redis - db - redis db: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: secret_password MYSQL_DATABASE: myapp volumes: - db_data:/var/lib/mysql # 使用命名数据卷持久化数据库 redis: image: redis:alpine command: redis-server --appendonly yes # 覆盖默认启动命令 volumes: # 在Compose级别声明数据卷 db_data: # 卷名关键部分解析services定义多个容器服务。buildvsimagebuild指定构建路径image指定从现有镜像运行。ports映射端口格式主机端口:容器端口。volumes挂载卷。可以是主机路径也可以是Compose文件中声明的顶级volumes。environment设置环境变量。可以使用字典或数组格式。depends_on声明服务间的启动依赖关系。注意它只控制启动顺序并不保证依赖的服务如MySQL在Web应用启动时已经完全就绪。对于这种“健康检查”需求需要更复杂的配置或启动脚本。6.2 常用命令与实战演练有了Compose文件管理整个应用栈就变得异常简单。启动所有服务docker-compose up # 后台启动 docker-compose up -d查看服务状态docker-compose ps查看服务日志# 查看所有服务的日志 docker-compose logs # 查看特定服务的日志并跟随输出 docker-compose logs -f web停止并移除所有容器、网络docker-compose down # 同时移除数据卷危险会删除数据库数据 docker-compose down -v在运行中的服务上执行命令# 在web服务容器中执行bash docker-compose exec web /bin/bash # 在db服务容器中连接MySQL docker-compose exec db mysql -u root -p重新构建镜像并启动docker-compose up --build实战场景开发环境与生产环境配置分离一个实用的技巧是使用多个Compose文件。例如创建docker-compose.yml作为基础配置docker-compose.override.yml用于开发环境配置代码挂载、调试工具docker-compose.prod.yml用于生产环境配置生产级日志、资源限制。运行时通过-f参数指定# 开发环境默认会合并docker-compose.yml和docker-compose.override.yml docker-compose up # 生产环境 docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d7. 生产环境部署考量与高级运维技巧将Docker用于生产环境远不止docker run那么简单。你需要考虑安全性、资源限制、监控、日志收集和网络配置等一系列问题。7.1 容器安全与资源限制非Root用户运行默认情况下容器内的进程以root用户运行这存在安全风险。最佳实践是在Dockerfile中创建一个非root用户并以此用户运行应用。FROM node:16-alpine RUN addgroup -g 1001 -S nodejs adduser -S nodejs -u 1001 USER nodejs # 切换用户 COPY --chownnodejs:nodejs . . CMD [node, app.js]资源限制防止单个容器耗尽主机资源。# 运行容器时限制CPU和内存 docker run -d \ --name my_app \ --cpus1.5 \ # 限制使用1.5个CPU核心 --memory512m \ # 限制内存为512MB --memory-swap1g \ # 限制内存交换分区为1GB nginx在Compose文件中也可以配置services: web: deploy: resources: limits: cpus: 0.50 memory: 256M reservations: cpus: 0.25 memory: 128M7.2 网络配置容器间通信与对外暴露Docker提供了几种网络模式bridge默认模式。为每个容器分配IP容器间可以通过IP通信主机需要通过端口映射访问容器。host容器直接使用主机网络性能最好但端口容易冲突。none禁用网络。overlay用于Docker Swarm集群实现跨主机的容器通信。自定义网络默认的bridge网络下容器间只能通过IP访问。创建自定义网络后容器间可以通过容器名互相访问这更方便。# 创建自定义网络 docker network create my_app_net # 将容器连接到自定义网络 docker run -d --name web --network my_app_net nginx docker run -d --name db --network my_app_net mysql # 现在在web容器中可以直接 ping db在Compose中默认就会为项目创建一个自定义网络所有服务默认加入并通过服务名互通。7.3 日志与监控日志管理生产环境需要将容器日志集中收集如使用ELK栈Elasticsearch, Logstash, Kibana。Docker支持多种日志驱动json-file,syslog,journald,gelf,fluentd等。可以在daemon.json中全局配置也可以在docker run时通过--log-driver指定。监控容器docker stats实时查看容器的CPU、内存、网络IO等使用情况。docker top container查看容器内运行的进程。对于大规模部署需要集成专业的监控系统如Prometheus配合cAdvisor收集容器指标和Grafana进行可视化。7.4 使用Docker Registry搭建私有镜像仓库对于企业应用将镜像推送到公共的Docker Hub是不安全的。我们需要搭建私有仓库。 使用Docker官方提供的registry镜像可以快速搭建# 拉取registry镜像 docker pull registry:2 # 运行私有仓库容器 docker run -d \ -p 5000:5000 \ --name registry \ -v /path/to/registry-data:/var/lib/registry \ registry:2现在一个私有仓库就在本地的5000端口运行了。你可以这样使用它# 1. 给本地镜像打上私有仓库的标签 docker tag my-flask-app:latest localhost:5000/my-flask-app:latest # 2. 推送到私有仓库 docker push localhost:5000/my-flask-app:latest # 3. 从其他机器拉取需要修改Docker守护进程配置信任该私有仓库 docker pull your-server-ip:5000/my-flask-app:latest对于生产环境你需要为私有仓库配置HTTPS通常使用Nginx反向代理并配置SSL证书和用户认证。8. 常见问题排查与实战避坑指南即使按照教程操作也难免会遇到各种问题。这里汇总了一些高频问题和解决方法。8.1 安装与启动类问题问题Docker Desktop启动失败提示“Virtualization support not detected”。原因Windows的Hyper-V或WSL 2依赖的虚拟化功能未开启或与其他软件冲突。解决进入BIOS确保CPU虚拟化Intel VT-x/AMD-V已启用。在“Windows功能”中确保“Hyper-V”、“Windows Subsystem for Linux”和“虚拟机平台”已勾选。彻底关闭并卸载其他虚拟化软件如VMware Workstation, VirtualBox的旧版本安卓模拟器。以管理员身份运行PowerShell执行bcdedit /set hypervisorlaunchtype auto然后重启。如果使用WSL 2确保已安装并设置为默认版本wsl --set-default-version 2。问题在Linux上执行docker命令提示“Permission denied”。原因当前用户不在docker组中。解决将用户加入docker组后必须注销并重新登录或者执行newgrp docker命令使组变更立即生效。8.2 镜像与容器操作类问题问题docker pull或docker push速度极慢。解决配置国内镜像加速器具体方法见本文第3.3节。对于push到私有仓库慢可能是网络问题检查仓库服务器带宽和防火墙设置。问题容器启动后立即退出Exited。排查步骤docker logs container_id查看容器退出的日志这是最重要的线索。docker run -it image /bin/sh尝试以交互模式启动并进入shell手动执行你的启动命令如python app.py看是否有错误输出。检查Dockerfile中的CMD或ENTRYPOINT指令是否正确命令是否存在。检查容器内应用是否在前台运行。Docker容器要求主进程在前台运行如果应用是后台服务如默认的Nginx、MySQL它们会自己处理如果你的脚本执行完就退出容器也会退出。这时可以用tail -f /dev/null这类命令保持容器运行但更好的方法是修正应用使其在前台运行。问题容器内无法连接到其他容器如数据库。排查步骤确认容器是否在同一个Docker网络中。使用docker network ls和docker network inspect network_name。在应用容器内尝试ping数据库的服务名或容器名。检查数据库容器的端口是否确实在监听netstat -tulnp以及防火墙设置。在Compose中使用depends_on只能控制启动顺序数据库可能还没完成初始化。应用需要有重试连接数据库的逻辑。8.3 存储与资源类问题问题Docker占用了大量磁盘空间。清理方法# 删除所有已停止的容器 docker container prune # 删除所有未被使用的镜像悬空镜像 docker image prune # 删除所有未被使用的数据卷谨慎 docker volume prune # 一键清理所有未被使用的资源容器、镜像、网络、构建缓存 docker system prune -a注意docker system prune -a会删除所有未被容器引用的镜像包括你可能想保留的中间镜像使用前请确认。问题容器运行一段时间后内存持续增长最终被OOM Kill。排查使用docker stats观察内存变化。进入容器使用top或ps命令查看哪个进程内存占用高。检查应用本身是否存在内存泄漏。为容器设置合理的内存限制-m让系统在容器超标前就限制它而不是直接杀死。8.4 网络与端口类问题问题docker run -p 80:80时报错“端口已被占用”。解决使用netstat -tulnp | grep :80或lsof -i:80查找是哪个进程占用了主机的80端口。停止冲突的进程或者修改-p参数映射到主机其他空闲端口如-p 8080:80。问题在容器内无法访问外部网络如ping不通百度。排查检查主机自身的网络是否正常。检查Docker守护进程的网络配置特别是如果使用了自定义的bip或dns。重启Docker服务sudo systemctl restart docker。从安装配置、日常使用、镜像构建到多服务编排和生产运维Docker提供了一个强大而完整的生态系统。掌握它意味着你掌握了现代应用交付和部署的一项核心技能。刚开始接触时概念可能有点多命令也容易记混这都很正常。我的建议是不要试图一次性记住所有命令而是从一个小项目开始比如把一个简单的静态网站或者Python脚本容器化在实践中反复使用docker run、docker ps、docker logs这几个最常用的命令。遇到问题就查文档、搜错误信息或者回来看这篇指南里的排查思路。积累一段时间后你会发现这些命令和概念就像肌肉记忆一样自然。最后再分享一个小技巧善用docker-compose它能将复杂的多容器应用定义在一个文件里无论是开发、测试还是部署一键启动和停止能为你节省大量重复劳动的时间。