尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Ubuntu安装Docker全攻略:从零配置到容器实战

Ubuntu安装Docker全攻略:从零配置到容器实战 最近好几个朋友都在问我同一件事Ubuntu 上装 Docker到底怎么才能一次装成功说实话网上一搜全是教程但很多教程只贴命令不讲原因小白照着敲完报错一个接一个最后还得回来搜“Ubuntu docker 安装失败”。这个问题我太熟悉了从 Ubuntu 16.04 一路用到 24.04Docker 的安装方式也改过好几轮踩过的坑比很多人见过的命令都多。这篇就把 Ubuntu 安装 Docker 的全过程写清楚面向完全没接触过 Docker 的小白——先讲清楚 Docker 是干嘛的再一步步装完 Docker Engine顺便把免 sudo 配置、镜像加速、Compose 插件和几个经典练手容器都带一遍。每一条命令我都会解释它做了什么为什么要这么写。你跟着走完机器上就是一个能正常拉镜像、跑容器的 Docker 环境。1. 先花五分钟搞懂 Docker 到底是什么再动手装1.1 用“集装箱公寓”来理解 Docker很多新手一上来就急着复制安装命令结果装完还是不知道自己在做什么。在敲任何命令之前我建议你先花五分钟把 Docker 的核心模型搞清楚。把一台 Ubuntu 服务器比作一栋公寓楼Docker 就是给每个住户发了一个集装箱。你在这个集装箱里放什么软件、用什么系统、安什么依赖都由你自己定不会影响隔壁。容器和容器之间相互隔离但共享大楼的水电——也就是宿主机内核。这个比喻虽然不完全精确但对入门来说非常管用Docker 容器就是一个独立的小环境里面可以跑你想要的任意 Linux 软件而不需要真的去装一个完整的虚拟机。我见过太多人误以为 Docker 容器里藏着一个完整的 Ubuntu 系统。实际上容器里通常只有运行某个软件所必需的文件和依赖它启动时直接使用宿主机内核。这也是为什么 Docker 容器能做到秒级启动而虚拟机往往要等上好几分钟。1.2 Docker 和虚拟机的本质区别既然聊到虚拟机我就把两者的差异说透。很多从 Windows 过来的用户第一次接触容器时总喜欢拿它跟 VMware、VirtualBox 里的虚拟机对比。简单整理了一张表对比维度Docker 容器传统虚拟机启动速度秒级分钟级资源占用小多个容器共享内核大每个都要完整操作系统隔离级别进程级隔离硬件级隔离镜像体积通常几十到几百 MB通常几个 GB适用场景微服务、开发测试、CI/CD多系统共存、强隔离需求在 Ubuntu 上装 Docker你不需要像 Windows 那样再配一套 WSL2 或 Hyper-V因为 Linux 本身就具备容器运行所需的全部内核能力。很多新手在 VMware 虚拟机里装好 Ubuntu 后以为装 Docker 还要到 BIOS 里开虚拟化其实完全不用——你是在 Linux 内核上直接跑容器Docker Engine 不会要求你再套一层虚拟化。1.3 装完之后你能立刻得到什么一条命令拉起 MySQL 8.0、Redis、Nginx不需要手动去处理依赖关系每个服务跑在独立容器里不会因为某个软件的动态库冲突污染整个系统环境一致性本地能跑的容器放到服务器上也能跑配合 Docker Compose一条命令启动一整组服务。安装只是第一步后面拉镜像、建容器、做数据持久化我都会在这篇里演示。你把这套流程走完才算把 Docker 的基础链路真正打通。2. 安装前先检查三件事系统版本、apt 更新、旧版本残留2.1 确认你的 Ubuntu 版本和内核打开终端先确认系统版本cat /etc/os-release uname -rcat /etc/os-release会显示系统版本代号和名称uname -r显示当前内核版本。Docker 官方对内核的要求是 3.10 以上而 Ubuntu 18.04 及以上版本默认内核都是 4.15 以上所以基本都能满足。需要注意Docker 官方 apt 源对 Ubuntu 长期支持版本LTS的支持最稳定比如 18.04、20.04、22.04、24.04。如果你用的是非 LTS 的中间版本也能装但遇到问题时不排除兼容性风险。查看输出时重点看VERSION_CODENAME那一行后面添加软件源会用到。2.2 先把 apt 索引和系统基础包更新一遍sudo apt update sudo apt upgrade -y这一步不要跳过。很多小白在安装时报各种奇怪的依赖错误原因就是系统里的软件包索引长期没有更新apt 根本不知道有 docker-ce 这个包。apt update的作用是同步软件源里的包索引apt upgrade是把系统里已安装的软件升级到源里对应的最新版本。如果你是在生产服务器上操作担心升级引发问题至少也要把apt update执行一遍。如果upgrade之后系统提示需要重启我建议先重启再继续装 Docker因为有些内核模块需要在新内核下才能正常工作。2.3 清理系统里可能残留的旧 Docker 软件包sudo apt remove docker docker-engine docker.io containerd runc这条命令会卸载系统里已经存在的旧版 Docker 组件。docker和docker-engine是 Docker 早期的包名docker.io是 Ubuntu 官方源里自带的版本通常很老和官网的 docker-ce 不是一回事。如果之前用sudo apt install docker.io装过 Docker现在不卸载就安装新版大概率会碰到文件冲突。如果系统是全新的执行后提示“没有可卸载的软件包”这很正常不用慌。这里卸载旧包不会影响后续安装因为新版安装时会自动装好依赖。3. 官方仓库安装 Docker Engine逐条命令拆解3.1 先装好下载所需的依赖工具sudo apt install -y ca-certificates curlca-certificates是一套 CA 证书后面要用 HTTPS 方式安全地访问 Docker 官方源没有它连接会报证书错误curl是下载工具用来拉取 Docker 官方的 GPG 密钥。这两个包很小装起来很快。为什么不用 wget其实 wget 也可以只是 Docker 官方文档一直使用 curl而且 curl 在写脚本时更灵活。跟着官方走就好。3.2 导入 Docker 官方 GPG 密钥sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod ar /etc/apt/keyrings/docker.asc第一条命令创建一个专门存放密钥的目录/etc/apt/keyrings-m 0755是设置目录权限让 owner 有读写执行权限其他用户有读和执行权限。第二条命令把 Docker 官方的 GPG 公钥下载下来保存为docker.asc。这个公钥的作用是验证你下载的 docker 包确实来自 Docker 官方而不是被篡改或伪造的相当于给软件包加了一道防伪 seal。第三条命令chmod ar是让所有用户都能读取这个密钥文件。如果你跳过这步后面apt update时可能因为权限不足报错。这里提醒一句如果你在网上看到老教程让你用apt-key add那个方法官方已经不推荐了而且会留下全局信任的密钥安全性不好。用/etc/apt/keyrings存放是现在官方文档的标准做法。3.3 把 Docker 官方 apt 软件源写进系统echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release echo $UBUNTU_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null这行命令看着长拆开就明白了它往/etc/apt/sources.list.d/docker.list文件里写了一条 apt 软件源配置。$(dpkg --print-architecture)会自动判断你的 CPU 架构比如 amd64、arm64不用手动填$(. /etc/os-release echo $UBUNTU_CODENAME)会自动读取系统版本代号比如 22.04 就是 jammy24.04 就是 noble。stable表示使用 Docker 稳定版分支。执行完之后再刷新一次软件源sudo apt update看到输出末尾没有报错说明软件源已经生效。如果这里出现 “N: Skipping acquire...” 之类的提示多半是系统版本代号和官方源不对应或者网络不通。3.4 安装 Docker 引擎和配套组件sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin这里一次装了 5 个包简单说明各自职责docker-ceDocker 社区版主程序也就是 daemon负责管理容器生命周期docker-ce-clidocker 命令行工具你敲的docker run、docker ps全靠它跟 daemon 通信containerd.io容器运行时负责真正创建和运行容器是 Docker 的底层支撑docker-buildx-plugin多架构镜像构建插件现在构建镜像的标配docker-compose-pluginDocker Compose 插件后面第六章详细讲。下载量比较大耐心等一会儿。如果网络不好可以考虑配置国内镜像源之后再回来装但一般来说官方源的包下载速度还是可以接受的。3.5 启动 Docker 服务并设置为开机自启sudo systemctl enable --now docker sudo systemctl status dockerenable --now的意思是把 Docker 服务设为开机自启并立即启动。如果不加--now只会设置开机自启不会立刻启动容易让人误以为安装失败。执行systemctl status docker后只要看到active (running)就说明 Docker 服务已经在跑了。按q退出状态界面然后跑一下版本验证sudo docker version输出里会分Client和Server两部分。如果只看到 Client 没有 Server说明 daemon 没起来需要检查服务状态。看到 Server 部分说明整个引擎已经正常工作。4. 不想每次敲 sudo把当前用户加进 docker 组4.1 为什么默认 docker 命令要 root 权限刚装好的 Docker每次执行docker命令都要加sudo原因很简单Docker daemon 默认监听的是 Unix socket 文件/var/run/docker.sock而这个文件的所有者是root:docker组其他用户没有访问权限。很多小白嫌麻烦直接用sudo -i切到 root 再敲 docker 命令或者干脆用 root 账号登录系统。这样当然也能用但时间一长就容易出问题你忘了自己是在 root 下后面写脚本、配权限的时候会踩坑。更合理的做法是把当前用户加入docker组。4.2 创建 docker 组并把当前用户加进去sudo usermod -aG docker $USER这条命令把当前用户追加到docker组。-aG的-a表示追加不会把你从其他组里移除$USER是当前登录用户名。改完组之后需要重新登录会话才能生效。最快的办法是执行newgrp dockernewgrp会用新的组身份启动一个子 shell临时生效。但最彻底的方式还是退出当前 SSH 会话或重启虚拟机重新登录一次不然有时 docker 命令还是报权限不足。4.3 验证免 sudodocker ps docker run hello-world如果docker ps能正常显示表格而不是报Permission denied说明免 sudo 配置成功。这里必须强调一个安全常识docker 组的权限基本等同于 root 权限。因为用户可以挂载宿主机目录进容器一旦容器里有恶意程序可以间接读写宿主机文件。所以不要在生产服务器上随便给普通用户加 docker 组。自己开发机随便折腾生产环境还是要按最小权限原则来。5. 国内拉镜像太慢配置镜像加速器5.1 为什么 docker pull 经常卡住装好 Docker 之后你执行docker pull nginx或docker run nginx时Docker 会默认从 Docker Hub 拉取镜像。但 Docker Hub 的服务器不在境内国内网络访问经常不稳定表现为下载进度条不动、超时或者反复重试。解决思路很简单给 Docker 配置一个镜像加速器。它的原理是让 Docker 优先从一个更近、更快的镜像仓库拉取仓库里缓存了 Docker Hub 上热门镜像拉取速度会明显提升。每次docker pull时Docker 会依次尝试你在配置里写的加速地址。地址失效了换一个就行互不影响。5.2 修改 daemon.json 配置编辑 Docker 的守护进程配置文件/etc/docker/daemon.json。如果文件不存在直接创建sudo mkdir -p /etc/docker然后用 tee 写入配置sudo tee /etc/docker/daemon.json EOF { registry-mirrors: [ https://docker.mirrors.ustc.edu.cn, https://hub-mirror.c.163.com ] } EOFregistry-mirrors是一个数组可以填多个加速地址Docker 会按顺序尝试。上面是中科大和网易的公共加速地址。如果你用的是阿里云等云服务器也可以在对应容器镜像服务的控制台里找到每个账号专属的加速地址格式类似https://xxxx.mirror.aliyuncs.com优先级更高拉取速度也更快。公共加速地址不保证永久可用哪天发现拉镜像又慢了把坏掉的地址从数组里删掉换一个新的即可。写完配置重启 Docker 让它生效sudo systemctl daemon-reload sudo systemctl restart dockerdaemon-reload让 systemd 重新读取 Docker 服务的配置restart docker才是真正重启服务。5.3 验证加速是否生效docker info | grep -A 4 Registry Mirrors如果能看到你配置的地址列表说明加速配置已经生效。接着实际拉一次镜像测试速度docker pull nginx正常情况下下载速度应该比配置前肉眼可见地快很多。拉取完成后docker images就能看到nginx镜像了。6. Docker Compose 插件也要安排上多容器编排离不开它6.1 为什么需要 Compose当你只有一个容器时docker run够用。可项目稍微复杂一点要同时跑前端、后端、数据库、缓存每个服务都手敲一长串docker run命令管理起来非常痛苦。Docker Compose 就是来解决这个问题的。你把所有服务写在一个compose.yaml文件里定义每个服务用什么镜像、映射哪些端口、设置什么环境变量、挂载哪些数据卷然后一条docker compose up -d全部启动一条docker compose down全部停止。对于本地开发和个人项目来说这是最实用的编排方式。6.2 确认或安装 compose 插件如果你在 3.4 节一次性安装了docker-compose-plugin那 compose 已经装好了。当时没装的话现在补上sudo apt install -y docker-compose-plugin注意新版 Docker 的命令是docker compose中间有一个空格和旧版的独立命令docker-compose带横杠不是同一个东西。旧版是 Python 写成的独立程序现在官方主推的是集成到 Docker CLI 里的插件功能更新更及时不建议再手工安装旧版。6.3 验证并给一个最小示例docker compose version能显示版本号就说明插件可用。为了让你直观感受 compose 的用法我写一个最简单的示例创建一个compose.yamlservices: web: image: nginx:latest ports: - 8080:80 db: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: root123 volumes: - mysql_data:/var/lib/mysql volumes: mysql_data:在文件所在目录执行docker compose up -d会看到它依次拉取 nginx 和 mysql 镜像然后启动两个容器。docker compose ps可以查看整体状态。新版 compose 文件不需要写version字段直接以services开头就行。这段配置里已经用到了环境变量和数据卷的概念这些都是生产环境天天要用的。环境变量是往容器里传配置的最简单方式数据卷则用来解决容器删除后数据丢失的问题下一章我用 MySQL 再具体演示。7. 安装完先拿三个容器练手把核心概念跑明白7.1 hello-world跑第一个容器docker run hello-world这是所有 Docker 新手的第一个容器也是验证环境是否正常的标准方式。执行后Docker 会先在本地查找hello-world镜像找不到就去你配置的镜像加速地址拉取然后启动容器在终端打印一段英文说明最后容器自动退出。看到Hello from Docker!那一行安装就正式宣告成功了。这个镜像只有几 KB非常适合用来验证“拉取-创建-启动-输出-退出”的完整链路。7.2 Nginx理解端口映射和后台运行docker run -d --name nginx-test -p 8080:80 nginx这条命令拆开看-d后台运行不会占住你的终端--name nginx-test给容器起个名字后面管理方便-p 8080:80把宿主机的 8080 端口映射到容器里的 80 端口。容器内部跑的是 nginx 默认 80 端口宿主机暴露 8080这样从外部访问http://localhost:8080就能看到 nginx 欢迎页nginx使用的镜像名。启动后访问验证curl http://localhost:8080能看到一堆 HTML 内容。如果是在云服务器上记得在安全组里放行 8080 端口否则端口映射做了也访问不通。这也是很多新手明明容器起来了浏览器却打不开页面的最常见原因。测试完停掉并删除容器docker stop nginx-test docker rm nginx-test7.3 MySQL 8.0环境变量、数据卷和容器内交互这一节对应很多人实际要用的“Docker 安装 MySQL 8.0 并使用”。先看完整命令docker run -d \ --name mysql-test \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD123456 \ -e MYSQL_ROOT_HOST% \ -v mysql_data:/var/lib/mysql \ mysql:8.0每个参数都值得好好讲-e MYSQL_ROOT_PASSWORD123456通过环境变量设置 MySQL root 密码。容器里运行的 MySQL 初始化时会读取这个环境变量来创建 root 账号密码-e MYSQL_ROOT_HOST%默认 MySQL 的 root 账号只允许从 localhost 连接这个变量改成%表示允许任意主机连接。这样你才能从宿主机或远程用客户端工具连上它。测试环境用这个没问题生产环境千万别开风险太大-v mysql_data:/var/lib/mysql创建一个名为mysql_data的数据卷挂载到容器里的/var/lib/mysql目录。MySQL 的数据文件都存在这个目录下。没有这行容器一旦删除数据库里的数据全部消失。启动后进入容器验证docker exec -it mysql-test mysql -uroot -p输入刚才设置的密码进入 MySQL 命令行执行show databases;看到information_schema、mysql、performance_schema、sys这些系统库说明 MySQL 已经正常运行。数据卷的价值体现即使执行docker rm -f mysql-test把容器删了只要mysql_data这个命名卷还在再创建一个挂载同一卷的 MySQL 容器数据都还在。这就是持久化。7.4 常用容器管理命令速查命令作用docker ps查看运行中的容器docker ps -a查看所有容器含已退出docker images查看本地镜像列表docker logs -f 容器名实时查看容器日志docker exec -it 容器名 bash进入容器内部执行命令docker start/stop/restart 容器名启动/停止/重启容器docker rm 容器名删除容器docker rm -f 容器名强制删除运行中的容器这些命令是日常使用频率最高的建议先记下来。Docker 的完整命令体系很大但小白阶段掌握这些足够应对绝大多数场景。8. 常见报错和彻底卸载方案8.1 不同 Ubuntu 版本下的安装差异Ubuntu 18.04、20.04、22.04、24.04 都可以直接用官方源安装区别只是系统版本代号自动识别Ubuntu 16.04 及以下的内核太老新版 Docker 基本不支持建议先升级系统不要用snap install docker安装 Docker。snap 版权限管理特殊路径也跟传统安装不一样很多容器跑起来会遇到奇怪的权限问题排查难度很大。8.2 安装启动过程中最常遇到的几个报错报错 1E: Unable to locate package docker-ce先确认sudo apt update执行过了再检查/etc/apt/sources.list.d/docker.list文件内容里的系统版本代号是否正确。最常出错的原因是从网上复制命令时把jammy、noble写死了而实际系统版本不对。报错 2Permission denied while trying to connect to the Docker daemon socket没有免 sudo 权限或者加入 docker 组之后没有重新登录。重新退出 SSH 再连接或者重启虚拟机一次。报错 3Cannot connect to the Docker daemon at unix:///var/run/docker.sockdaemon 没起来。执行sudo systemctl status docker看具体原因再用sudo systemctl start docker启动。报错 4端口被占用比如 3306 已经被本机 MySQL 占了再启动 MySQL 容器会报端口冲突。解决方法是换宿主机映射端口把-p 3306:3306改成-p 3307:3306。报错 5在 VMware/VirtualBox 虚拟机里装 Docker启动崩溃或网卡异常首先要明确在 Linux 虚拟机里装 Docker Engine 是不需要额外开启嵌套虚拟化的Docker 直接跑在 Linux 内核上。如果你看到类似virtualization support not detected的提示那通常是 Windows 平台装 Docker Desktop 时的问题不是 Ubuntu 里装 Docker Engine 的问题别混淆了。Ubuntu 的 Docker 只关心内核版本够不够跟 BIOS 里的 VT-x 没有关系。8.3 完整卸载 Docker 并清理数据卸载和安装一样重要。完整卸载 Docker 的命令sudo apt purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin sudo apt autoremove如果配置过 docker 组并加入了用户可一并删除sudo groupdel docker删除残留数据和软件源配置文件sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd sudo rm -f /etc/apt/sources.list.d/docker.list sudo rm -f /etc/apt/keyrings/docker.asc这里特别提醒/var/lib/docker是 Docker 的默认数据目录里面包含所有镜像、容器、数据卷。执行rm -rf前一定要确认这些数据不需要了否则删了就找不回来。如果有想保留的数据卷先备份再删除。最后分享一个我的个人习惯每装完一台 Ubuntu 的 Docker 环境我不会急着部署业务而是先做三件事——配置好镜像加速、跑一个 Nginx 容器测试端口映射、再起一个 MySQL 容器确认数据卷正常。整套流程十分钟左右但能把网络、端口、持久化这几个最容易出问题的点全部验证一遍。以后再在项目里用 Docker 部署你会发现比在裸机上折腾依赖省心太多。照着这篇装好了你跨过的不只是“装 Docker”而是“会用 Docker”后面的事就顺了。
返回列表