从入门到实战:Docker容器化部署全链路详解
2026/9/16 3:53:42 网站建设 项目流程

很多朋友问我,Docker到底是个什么东西,为什么身边搞开发、搞运维、甚至搞测试的同事都在用。每次我都想用一句话讲清楚,但发现真的很难——不是概念复杂,而是它解决的问题太贴近日常了,三言两语说不透。今天这篇我就从实际使用角度出发,把Docker从概念到落地的完整链路捋一遍。不管你是刚接触命令行的新手,还是已经被各种报错折磨过的“准用户”,这篇文章都能给你一条清晰、可执行的路径。

我最早接触Docker,是因为要在本地搭一套和线上一致的开发环境。那时候最痛苦的事就是:代码在本地跑得好好的,一发到服务器就各种幺蛾子——JDK版本不对、Redis没装、MySQL编码不对、Linux路径和Windows不一样。每次排查环境问题的时间比写代码还长。后来用了Docker,这些折腾基本绝迹了。它本质上就是把你应用运行所需要的一切——代码、运行时、系统库、配置文件——打包成一个标准化的“盒子”,这个盒子在谁的机器上都能跑出一模一样的效果。

这篇实战笔记会覆盖几个核心部分:Docker到底是什么、和虚拟机的本质区别、Windows和Linux下的安装全流程、高频命令速查、MySQL和Redis的真实部署案例、docker compose编排,以及我踩过无数次坑之后总结出来的问题排查清单。内容偏实用,每个步骤都能直接抄作业。

1. 内容整体设计与思路拆解

1.1 Docker到底是什么:一个装好一切的“标准货柜”

先别急着敲命令,我们先把概念理清楚。Docker是一个开源的容器化平台,它让你可以把应用及其依赖打包成一个轻量、可移植的容器。这个容器可以直接运行在任何安装了Docker的机器上,不用管底层操作系统是什么。

打个比方,以前分发应用就像把一台没组装的电脑寄给别人——CPU、内存、硬盘、显示器分开打包,对方收到还得自己组装、装系统、装驱动,中间任何一个环节版本不匹配就开不了机。有了Docker之后,你直接把整台“装好系统、装好软件、配置完毕”的电脑装进一个标准货柜里寄过去,对方只需要有电(装了Docker),就能开机使用。

这个“标准货柜”在Docker里叫镜像(Image)。镜像跑起来之后,就是一个容器(Container)。镜像和容器的关系,可以理解成程序与进程、类与实例的关系——镜像是静态的、只读的模板;容器是镜像运行时的动态实例,可以启动、停止、删除。

1.2 镜像、容器、仓库:三个你必须先记住的名词

在Docker的世界里,有三个最核心的概念,几乎所有操作都围绕它们展开:

  • 镜像(Image):一个只读的模板,定义了容器内要有什么软件、什么配置、什么环境变量。镜像是分层构建的,可以理解为每一层都是一个增量补丁。
  • 容器(Container):镜像的运行实例。一个镜像可以启动多个容器,它们相互隔离,互不影响。
  • 仓库(Registry):集中存放镜像的地方。最常用的是Docker Hub——官方的“镜像应用商店”。你从仓库拉取(pull)镜像到本地,也可以把自己做的镜像推送(push)上去分享给别人。

这三者之间的关系是:从仓库拉取镜像 → 基于镜像创建并运行容器 → 容器运行你的应用。理解了这个闭环,后面所有命令都不会让你感到困惑。

1.3 为什么不用虚拟机:容器赢在“轻”和“快”

很多人会问:虚拟机也能隔离环境、也能打包分发,为什么要用Docker?这个问题我当年也纠结过,直到我实际对比了一次。

虚拟机(VM)是对硬件层做虚拟化,每个虚拟机里都要装一个完整的操作系统(Guest OS),动辄几个GB起步,启动要等几分钟,占用的CPU、内存都是实打实被扣走的。

容器则是对操作系统层做虚拟化,所有容器共享宿主机同一个内核,容器里只打包应用及其依赖的系统库,没有独立操作系统。所以容器的镜像小到几百MB甚至几十MB,启动是以毫秒到秒级计算的。

对比维度虚拟机Docker容器
隔离级别硬件级虚拟化操作系统进程级隔离
镜像大小GB级起步MB级为主
启动速度分钟级毫秒~秒级
资源占用每个VM独占资源多个容器共享内核
密度一台机器跑几个VM就吃力一台机器轻松跑几十个容器

对开发者和运维来说,这种差异意味着:本地开发环境秒级拉起、测试环境几秒钟批量创建、生产环境资源利用率大幅提升。这也是为什么容器技术被认为是云原生时代的基石。

1.4 镜像加速:拉不下来镜像,一切白搭

镜像下载慢、超时,是新手遇到最多的问题,没有之一。Docker Hub的服务器在境外,直接从官方源拉镜像经常几KB/s甚至直接超时。

解决方案就是配置镜像加速器。国内多家云服务商都提供免费的Docker镜像加速服务,比如阿里云、腾讯云、华为云都提供了各自的加速地址,部分还有网易、中科大等公共加速地址。它们的原理都一样:把这些加速器配置为Docker的registry mirror,拉镜像时Docker会先从加速器拉取,加速器再回源Docker Hub并缓存。

配置方式很简单,在Docker的配置文件daemon.json里加上registry-mirrors配置即可。Windows和Mac端在Docker Desktop的设置界面里也可以直接配置,我们在下一章的安装环节具体讲。

2. 环境准备与安装全流程

2.1 Windows安装:Docker Desktop与WSL2的配合

Windows上安装Docker,目前官方推荐的路径是Docker Desktop。它底层依赖一个后端环境,现在主流是WSL2(Windows Subsystem for Linux 2)。安装前有几项前置检查一定要做,不然启动时会报“virtualization support not detected”之类的错误。

先确认你的CPU虚拟化已经在BIOS里打开。开机进BIOS(一般是按Del或F2),找Intel Virtualization Technology(Intel VT-x)或AMD SVM Mode,设为Enabled。这一步不做,装完Docker Desktop会直接启动失败,报错提示找不到虚拟化支持。

第二步是启用Windows功能。控制面板 → 程序 → 启用或关闭Windows功能,勾选“适用于Linux的Windows子系统”和“虚拟机平台”。完成后重启电脑,然后在PowerShell(管理员)里执行:

wsl --set-default-version 2

这样WSL的默认版本就是2了。Docker Desktop默认优先使用WSL2后端,相比老一代的Hyper-V方案,启动更快、资源占用更低。

接下来去Docker官网下载Docker Desktop for Windows(注意ARM和x86版本别下错),一路Next安装即可。安装完成后启动,系统托盘会出现Docker图标,打开终端执行:

docker version

能看到Client和Server两段信息,说明安装成功。如果只有Client没有Server,多半是引擎没启动起来,检查一下Docker Desktop日志和WSL状态。

2.2 Linux安装:Ubuntu和CentOS的两种姿势

Linux下安装Docker最怕用旧教程。很多网上搜到的教程还在用docker.io这种老包,或者手动添加已经废弃的仓库源。这里分享两条被验证过无数次的可靠路径。

Ubuntu/Debian系推荐使用官方脚本一键安装:

curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh

这个脚本会自动配置官方或镜像源,安装Docker Engine、containerd和CLI工具,安装完再执行:

sudo systemctl enable --now docker sudo systemctl status docker

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

然后安装:

sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin sudo systemctl enable --now docker

有个CentOS 7的老用户需要注意,CentOS 7自带的3.10内核比较老,部分Docker新特性用不了。如果要用较新的Docker版本,建议先把内核升级到5.x,否则可能出现iptables相关的网络异常。

2.3 安装后的初始化:用户组、镜像加速、开机自启

装完Docker不是终点,还有三步初始化操作非常重要,很多教程会略过。

第一步,把当前用户加入docker组,免去每次敲命令都要sudo的烦恼:

sudo usermod -aG docker $USER newgrp docker

这里有个坑要注意:修改完用户组后,必须重新登录终端或执行newgrp docker才生效。如果忘记这一步,会一直报“permission denied while trying to connect to the Docker daemon socket”。

第二步,配置镜像加速。Linux下修改/etc/docker/daemon.json

{ "registry-mirrors": [ "https://docker.m.daocloud.io", "https://dockerproxy.com", "https://docker.nju.edu.cn" ] }

改完重启Docker:sudo systemctl restart docker。Windows用户则在Docker Desktop的设置 → Docker Engine里,把同一个JSON内容贴进去,点击Apply & Restart。

第三步,确认开机自启。Ubuntu/Debian系用systemctl管理的话,enable --now已经同时设置了开机自启。如果用的是Docker Desktop,它的设置里默认有启动时自动启动的选项,记得勾上。

3. Docker常用命令与核心配置解析

3.1 镜像管理命令:拉取、查看、删除

镜像操作是整个Docker使用频率最高的动作,命令本身不难,搞清楚几个核心的就够用。

# 拉取一个镜像,默认从Docker Hub拉取latest标签 docker pull mysql:8.0 # 查看本地所有镜像 docker images # 查看镜像详细信息 docker inspect mysql:8.0 # 删除镜像 docker rmi mysql:8.0 # 清理所有悬空镜像(没有标签的中间层镜像) docker image prune

这里有一个细节容易踩坑:docker pull不指定标签时默认拉取latest。生产环境强烈建议指定明确的版本号。我之前就遇到过,某天重新部署时把latest里的MySQL 8.0.36拉下来,但线上跑的还是8.0.28,一个配置参数行为变了,排查了很久。镜像标签锁定版本,是最基础的环境可复现性保障。

3.2 容器生命周期命令:run、start、stop、rm

容器的命令是另一个高频面试题,也是实际使用中最常敲的。最核心的还是docker run,它的参数非常多,但有几组是必须掌握的:

docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=123456 \ -v /data/mysql:/var/lib/mysql \ --restart=always \ mysql:8.0

我来逐个拆解这几个参数的含义:

  • -d:后台运行容器(detach模式),不会霸占当前终端
  • --name:给容器起一个名字,方便后续管理
  • -p 3306:3306:端口映射。宿主机3306端口映射到容器内3306端口。这样外部访问宿主机IP+3306就能进入MySQL
  • -e:设置环境变量。这里设置了MySQL的root密码
  • -v /data/mysql:/var/lib/mysql:数据卷挂载。把宿主机目录挂到容器内目录,容器删除后数据还在宿主机上
  • --restart=always:容器意外退出或Docker重启后自动拉起容器

其他常用的容器操作命令:

# 查看运行中的容器 docker ps # 查看所有容器(包括已停止的) docker ps -a # 启动一个已存在的容器 docker start mysql8 # 停止一个容器 docker stop mysql8 # 删除容器(需先停止) docker rm mysql8 # 强制删除运行中的容器 docker rm -f mysql8 # 进入容器内部 docker exec -it mysql8 bash

docker exec -it是调试时最常用的命令。进入容器后,你能像在一台独立Linux机器里一样操作,查看日志、改配置、跑命令。-it-i(交互式)和-t(分配终端)的组合,少一个都会导致无法正常交互。

3.3 日志、资源查看与清理:运维离不开的几组命令

实际使用中,容器运行出问题,第一件事就是看日志。

# 查看容器日志(最新100行) docker logs --tail 100 mysql8 # 实时跟踪日志输出 docker logs -f mysql8 # 带时间戳查看日志 docker logs -t mysql8

docker logs -f是排障利器。之前我在容器里部署Java应用,启动后一直没反应,执行docker logs -f才发现是内存参数设置导致的OOM,日志里清清楚楚。没有这个命令,问题定位难度会大很多。

资源占用情况也是日常要关注的:

# 查看所有容器的CPU、内存、网络占用 docker stats # 查看容器的进程信息 docker top mysql8 # 查看容器的资源使用明细 docker inspect mysql8 | grep -i memory

最后是清理:

# 清理所有已停止的容器 docker container prune # 清理所有未被使用的网络 docker network prune # 一键清理:容器 + 网络 + 悬空镜像 + 构建缓存 docker system prune -a

docker system prune -a这个命令杀伤力很大,会删除所有没有被容器使用的镜像,磁盘空间告急时用一次能腾出大量空间。但有经验的人都明白一个道理:执行之前先确认有没有私有的、无法重新拉取的本地镜像,否则就是灾难。

3.4 数据卷与网络:让容器数据持久化、容器间互通的两大支柱

容器是“用完即走”的,如果没有数据卷,容器一删除,里面写入的数据全部丢失。**数据卷(Volume)**就是Docker提供的持久化方案。

挂载数据卷前面已经演示过,这里补充三种方式:

  • 匿名卷-v /var/lib/mysql,不指定宿主机路径,Docker自动分配一块目录存储,后续管理比较麻烦,不推荐。
  • 命名卷-v mysql-data:/var/lib/mysql,Docker管理该卷的宿主机路径,复用性好。
  • 宿主机路径挂载-v /data/mysql:/var/lib/mysql,最直观,适合有固定宿主机目录要求的场景。

网络方面,Docker容器默认通过NAT网络与外界通信。多个容器之间要互相访问,最简单的方式是创建自定义网络:

docker network create my-net docker run -d --network my-net --name mysql8 mysql:8.0 docker run -d --network my-net --name app myapp

同一个自定义网络里的容器可以通过容器名直接互相访问。比如应用容器里配置数据库地址,直接写mysql8:3306就行,不需要去查IP。这个特性在docker compose编排中会被大量使用。

4. 实战:用Docker部署MySQL 8.0从零到可连接

4.1 需求分析与端口、目录、密码的规划

很多人第一次用Docker部署MySQL,就是因为本机或者公司的测试环境MySQL版本太乱,想用Docker快速拉起一个干净的实例。这个需求非常典型,也最适合作为第一个练手项目。

动手之前先想清楚三件事:

  1. 端口:宿主机3306是否被占用?如果本机已经有MySQL在跑,映射宿主机端口要换成3307之类的未占用端口。
  2. 数据目录:决定把数据落在宿主机的哪个目录,这个目录后续要定期备份。
  3. 密码:root密码不要用太简单的,即使只是测试环境。

我这边的规划是:宿主机端口3306,数据目录/data/mysql,root密码Root@2024,版本锁定mysql:8.0

4.2 完整启动命令与参数逐项说明

第一步,创建宿主机数据目录并赋予适当权限:

sudo mkdir -p /data/mysql

第二步,执行run命令启动容器:

docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=Root@2024 \ -v /data/mysql:/var/lib/mysql \ -e TZ=Asia/Shanghai \ --restart=always \ mysql:8.0

这里比前面的示例多了个TZ=Asia/Shanghai环境变量,把容器时区设置为东八区。MySQL的时间函数与系统时区有强关联,不设置时区的话,默认UTC时间会和北京时间相差8小时,排查数据问题时会非常头疼。

第三步,验证容器是否正常运行:

docker ps docker logs --tail 20 mysql8

看到日志中ready for connections字样,说明MySQL已经正常启动。

4.3 数据持久化验证与远程连接配置

验证数据持久化是否生效,最简单的方式是:进入容器创建一个测试数据库,然后删除容器,再重新启动一个新容器挂载同一个数据卷,看看数据是否还在。

# 进入容器创建测试库 docker exec -it mysql8 mysql -uroot -pRoot@2024 -e "CREATE DATABASE test_persist;" # 删除容器(容器内的数据默认随之消失) docker rm -f mysql8 # 用相同参数重新创建容器 docker run -d --name mysql8 -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=Root@2024 \ -v /data/mysql:/var/lib/mysql \ -e TZ=Asia/Shanghai \ --restart=always \ mysql:8.0 # 检查数据是否还在 docker exec -it mysql8 mysql -uroot -pRoot@2024 -e "SHOW DATABASES;"

test_persist库仍然存在,说明数据卷挂载生效。这一步虽然简单,但我强烈建议每个新手都亲手验证一遍。只有自己确认过“容器删了数据还在”,才能真正理解数据卷的价值。

远程连接时,注意MySQL 8.0默认的认证插件是caching_sha2_password,老版本客户端可能连不上。如果遇到Authentication plugin 'caching_sha2_password' cannot be loaded的报错,进入容器执行以下SQL:

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'Root@2024'; FLUSH PRIVILEGES;

把root的认证方式改成mysql_native_password。生产环境建议单独创建专用账号并限制权限,不要图省事直接改root。

4.4 开机自启与容器异常恢复

--restart=always这个参数在前面出现过,这里重点说一下它的几种取值和适用场景:

restart策略行为适用场景
no容器退出不自动重启临时测试容器
on-failure[:max-retries]非正常退出才重启脚本任务
always始终重启,Docker启动时也会自动拉起数据库、中间件等常驻服务
unless-stopped手动停止后不再重启,其余情况自动重启调试过程中的服务

生产环境部署MySQL、Redis这类常驻服务,--restart=always是标配。Docker服务重启后,这些容器也会自动恢复,省去手动拉起的麻烦。

5. 实战进阶:Redis主从复制与Docker Compose编排

5.1 单机MySQL已经会了,Redis为什么还要主从

部署MySQL解决的是“数据库版本统一、环境干净”的问题。但很多业务系统还需要Redis做缓存,而且为了高可用,还要配主从复制。用Docker部署Redis主从的好处是:通过容器快速创建多个Redis实例,它们之间网络互通、配置隔离,模拟生产环境的主从拓扑非常方便。

主从复制的核心逻辑是:主库(Master)负责写操作,从库(Slave/Replica)负责读操作,主库把写操作的命令同步给从库。好处是三重的:读写分离提升吞吐量、数据热备份降低丢失风险、从库可以承担故障切换的职责。

5.2 docker compose文件编写:两个Redis实例一个compose搞定

docker compose的作用是:用YAML文件定义多个容器,一条命令自动创建和启动。它避免了手动敲大量docker run命令的繁琐,也让服务编排的配置有迹可循。

我新建一个目录redis-cluster,在里面创建docker-compose.yml

version: '3.8' services: redis-master: image: redis:7.0 container_name: redis-master ports: - "6379:6379" command: redis-server --appendonly yes volumes: - redis-master-data:/data networks: - redis-net redis-replica: image: redis:7.0 container_name: redis-replica ports: - "6380:6379" command: redis-server --replicaof redis-master 6379 --appendonly yes depends_on: - redis-master volumes: - redis-replica-data:/data networks: - redis-net volumes: redis-master-data: redis-replica-data: networks: redis-net: driver: bridge

注意几个关键点:

  • command字段覆盖默认启动命令,--replicaof redis-master 6379告诉从库去复制主库。这里写的是容器名redis-master,因为compose会自动把服务名解析为容器网络内的DNS名,这比写IP可靠得多。
  • depends_on保证主库先启动,从库后启动。但它只控制启动顺序,不等待主库完全就绪。如果主库初始化较慢,从库可能会因连接失败而重试——不过Redis的复制机制本身支持断线重连,短暂失败不影响最终一致。
  • volumesnetworks在文件底部定义,compose会创建对应的命名卷和自定义网络。

启动命令就一行:

docker compose up -d

查看状态和验证主从:

docker compose ps # 进入从库查看复制状态 docker exec -it redis-replica redis-cli info replication

输出中role:slavemaster_link_status:up表示从库已连接主库、复制链路正常。在主库写数据,从库能查到,整个主从就通透了。

5.3 实际部署一个前后端+中间件的完整组合

docker compose更大的威力在于编排整个应用栈。我之前给一个小型项目做了这样的编排:前端Nginx + 后端Java应用 + MySQL + Redis,外面套一层compose,一键部署整个项目。

这个compose的骨架大概是:

version: '3.8' services: frontend: image: nginx:1.24 ports: - "80:80" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro - ./dist:/usr/share/nginx/html:ro depends_on: - backend backend: build: ./backend environment: SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/mydb?useUnicode=true SPRING_REDIS_HOST: redis depends_on: - db - redis db: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: mydb volumes: - db-data:/var/lib/mysql redis: image: redis:7.0 command: redis-server --appendonly yes volumes: - redis-data:/data

这里backend服务用的是build指令,意味着它会读取./backend目录下的Dockerfile,构建本地镜像,而不是从仓库拉取。前后端服务之间通过服务名互相访问,环境变量里配置的数据库地址直接写db:3306、Redis地址写redis:6379,一切都在compose创建的网络里自动解析。

这种编排方式的体验,用一句话概括:从“搭环境半天”变成“一条命令跑通全栈”。团队新同事入职,clone代码后直接docker compose up -d,十分钟内本地环境就和线上一致了。

6. 常见问题与排查技巧实录

6.1 Docker Desktop启动失败:virtualization support not detected

这个报错信息很多人会在Windows上遇到。我排查过几次,出现这个提示通常有四个原因:

  1. BIOS虚拟化没开:重启进BIOS,确认VT-x/AMD-V已开启。
  2. Windows功能没开全:控制面板里确保“虚拟机平台”“适用于Linux的Windows子系统”都勾选了。
  3. Hyper-V冲突:如果机器上装了旧版VirtualBox或VMware,并且开启了硬件加速,可能与Docker Desktop的虚拟化冲突。要么关掉第三方虚拟机的嵌套虚拟化,要么卸载,二选一。
  4. WSL版本不对:检查wsl -l -v,确保发行版确实跑在WSL2上。如果是V1,执行wsl --set-version <发行版名> 2升级。

还有一个常被忽视的点:安装Docker Desktop后没有重启电脑。Windows的很多内核级功能(如Hyper-V、WSL2)需要重启才生效,这个步骤不能跳过。

6.2 docker: permission denied / Got permission denied(权限问题)

在Linux上装了Docker,执行docker ps时报:

permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock

原因:当前用户不在docker组里,没有权限访问Docker守护进程。解决办法前面提过,加到docker组并重新登录:

sudo usermod -aG docker $USER newgrp docker

如果还是报错,检查一下docker socket的权限:

ls -l /var/run/docker.sock

正常情况是rw-rw----,属主是root:docker。如果属主不对,可以临时改一下,但这属于非标准操作,最好还是找到为什么socket权限被改过的原因。

6.3 docker: failed to connect to the docker api at npipe:////./pipe/dockerdesktoplinuxen

这是Windows上的典型报错,说明Docker Desktop没有正常启动。处理顺序:

  1. 查看系统托盘Docker图标是否亮着;没有的话,手动启动Docker Desktop。
  2. 启动后等待30秒左右,确认引擎状态从Starting变成Running。
  3. 还不行就重启Docker Desktop:托盘右键 → Restart。
  4. 实在不行重启电脑,Windows上很多诡异问题重启就好了。

如果重启后依然报这个错误,多为WSL2内核损坏或未正确启动。执行wsl --shutdown关闭所有WSL进程,再启动Docker Desktop,基本能解决。

6.4 容器一直重启:CrashLoopBackOff现象

docker ps看到容器状态是RestartingRestarting (1) 2 seconds ago,说明容器启动后立刻崩溃退出,Docker在反复重启它。

排查思路非常固定:看日志。执行:

docker logs --tail 50 <容器名>

日志里通常有启动失败的根因。我遇到最多的情况是:

  • MySQL启动失败:通常是数据目录权限不对,或者my.cnf配置了宿主机路径但目录不存在。
  • 配置文件格式错误:compose文件或应用配置文件里YAML/JSON语法有问题,服务启动即报错退出。
  • 依赖服务还没就绪:比如后端启动时连不上数据库,连接超时后进程退出。虽然depends_on规定了顺序,但数据库未必已准备好接受连接,这时就要给应用加等待重试机制,或者在compose中用健康检查。

容器崩溃排查的黄金法则是:先看日志,别猜。绝大多数问题在日志里都能找到线索。

6.5 镜像下载慢或超时:加速器配置实操

配置了镜像加速器,拉取速度依然慢的,大概率是加速器本身不稳定。我推荐的做法是,在daemon.json里同时配置多个镜像源,并定期检查可用性:

{ "registry-mirrors": [ "https://docker.m.daocloud.io", "https://dockerproxy.com", "https://docker.nju.edu.cn" ] }

如果所有镜像源都失效或者内网环境无法访问外网,另一个思路是找一台能正常访问Docker Hub的机器,提前把镜像保存为tar包,再导入目标机器:

# 在能访问Docker Hub的机器上 docker pull mysql:8.0 docker save -o mysql8.tar mysql:8.0 # 拷贝到目标机器后导入 docker load -i mysql8.tar

这是离线环境部署的标准操作,虽然笨一点,但非常可靠。

6.6 容器内访问宿主机服务的特殊处理

容器默认是隔离的,容器里访问宿主机上的MySQL、Redis、API这类服务时,不能直接写localhost127.0.0.1,因为容器内的localhost指容器自身。

Linux上可以用172.17.0.1,这是Docker默认网桥的宿主机网关地址。Windows/macOS的Docker Desktop则可以直接使用host.docker.internal这个特殊域名。很多新手第一次遇到“容器里连不上宿主机服务”的问题,就是困在这里。

环境宿主机访问地址
Linux(默认bridge网络)172.17.0.1
Windows/macOS Docker Desktophost.docker.internal
使用host网络模式localhost(容器与宿主机共享网络栈)

7. 最终实操心得与建议

最后分享一些我个人在实际使用中的体会。

第一,Docker的学习曲线其实没有想象中陡峭,真正让小白的崩溃的往往不是概念,而是一堆底层环境问题——Windows的虚拟化、Linux的权限、加速器失效。把这些拦路虎提前排干净,后续的使用一定顺畅很多。

第二,一定要亲手敲一遍。看十篇教程不如自己从头到尾执行一条docker run命令。从拉镜像、起容器、映射端口、挂载数据卷,到排查一次容器崩溃,这些动作一旦形成肌肉记忆,Docker在你眼里就从“黑科技”变成了“顺手工具”。

第三,镜像tag锁版本、数据卷必须挂载、配置统一走compose。这三条习惯,能帮你避开绝大多数生产事故。我见过太多线上事故的根源,就是环境不一致。Docker给了我们一把应对这个问题的利器,但利剑要用得稳,前提是把地基夯实。

这个内容后续还可以扩展的方向很多:比如如何编写自己的Dockerfile、怎么做多阶段构建减小镜像体积、如何用docker compose做服务健康检查与自动恢复、怎么配合CI/CD实现提交代码自动部署。每一步都是独立的进阶主题,等你有了一定基础之后,可以逐个击破。

先说这么多。希望这篇实战笔记能帮你把Docker这块硬骨头啃下来,真正做到从概念到实践,一键跑通。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询