ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Ubuntu 22 安装配置 Docker 全攻略:从零到高效部署

Ubuntu 22 安装配置 Docker 全攻略:从零到高效部署 1. 从“能用”到“好用”为什么在Ubuntu 22上装Docker值得你花时间如果你刚接触Ubuntu 22或者从Windows/macOS转过来想找个能干净利落跑起各种开发环境、中间件的方法那Docker绝对是你绕不开的一环。它不是什么高深莫测的黑科技你可以把它理解成一个“集装箱系统”。以前你要跑一个MySQL数据库得在系统里下载、编译、配置版本冲突、依赖缺失是家常便饭。现在Docker直接给你一个打包好的、包含了MySQL及其所有运行环境的“集装箱”镜像你只需要一条命令就能把它“开箱”运行起来。这个集装箱和你的主机系统是隔离的不会污染你的环境用完即删干净清爽。在Ubuntu 22上这个体验尤其丝滑。作为长期支持版本Ubuntu 22的软件源稳定内核版本对容器技术的支持也足够新。但别以为apt install docker.io就万事大吉了官方源里的版本往往不是最新的而且权限管理、镜像加速这些细节如果不在一开始就处理好后面会平添无数麻烦。我见过太多人卡在Got permission denied while trying to connect to the Docker daemon socket这样的错误上或者拉取镜像慢如蜗牛还没开始用就先被劝退。所以这篇内容不是一份冷冰冰的官方文档翻译。我会结合自己从新手到在团队里推广Docker的踩坑经验带你走一遍在Ubuntu 22上从零安装、配置到验证Docker的完整流程。目标很简单让你装上的Docker不仅“能用”而且“好用”成为一个真正提升效率的工具而不是另一个麻烦的来源。2. 安装前的关键准备避开两个最常见的“起跑线”陷阱很多人一上来就照着教程敲命令忽略了准备工作结果第一步就卡住。在Ubuntu 22上安装Docker有两件事你必须先确认这能帮你省下至少80%的排查时间。2.1 内核与虚拟化支持你的硬件真的准备好了吗Docker容器依赖于Linux内核的cgroups和namespaces等特性。Ubuntu 22默认使用的内核版本5.15或更高完全满足要求这一点通常无需担心。但有一个更深层、更隐蔽的坑尤其对于使用笔记本电脑或在虚拟机上安装Ubuntu的用户虚拟化支持。你可能会在网络上看到“Docker Desktop failed to start because virtualisation support wasn‘t detected”这样的错误。这通常出现在Windows或macOS上安装Docker Desktop时但在Linux环境下如果你是在VMware或VirtualBox这类虚拟机里安装Ubuntu然后想再跑Docker同样需要宿主机的虚拟化支持被正确传递给虚拟机。怎么检查打开终端输入这条命令grep -E --color vmx|svm /proc/cpuinfo如果输出中有高亮显示的vmxIntel CPU或svmAMD CPU恭喜你你的CPU支持硬件虚拟化并且在物理机上通常已启用。如果没有任何输出这不一定代表你的CPU不支持。更可能的原因是在BIOS/UEFI中被禁用重启电脑进入BIOS设置找到类似“Intel Virtualization Technology”、“VT-x”、“AMD-V”或“SVM Mode”的选项确保其状态为“Enabled”。在虚拟机中运行Ubuntu你需要确保虚拟机的配置已开启嵌套虚拟化。例如在VMware中你需要关闭虚拟机然后编辑虚拟机设置在“处理器”选项中勾选“虚拟化Intel VT-x/EPT或AMD-V/RVI”。VirtualBox也有类似设置。注意对于绝大多数在物理机上直接安装Ubuntu 22的用户只要不是非常古老的电脑硬件虚拟化都是支持的且默认开启。这个检查主要是为了排除在虚拟环境中安装时可能遇到的底层障碍。2.2 彻底清理旧版本避免“幽灵”冲突这是另一个高频踩坑点。你的系统里可能通过apt安装过老旧的docker、docker.io或者尝试安装过docker-ce社区版但没成功。这些残留的包和配置会与新安装的官方Docker引擎产生冲突导致各种匪夷所思的错误。因此在安装新版本之前执行一次彻底的清理是绝对必要的。别怕以下命令只会移除Docker相关的程序不会影响系统其他部分sudo apt remove docker docker-engine docker.io containerd runc执行后apt会提示将要移除的软件包列表确认即可。但是apt remove并不会删除Docker在/var/lib/docker/目录下存储的镜像、容器、卷和网络配置等数据。如果你确定不需要这些数据比如你是全新学习可以手动删除以释放空间sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd如果你之前安装过Docker并有一些重要容器请谨慎执行删除命令或者先备份相关数据。完成清理后建议更新一下软件包索引确保后续安装能获取到最新的源信息sudo apt update3. 安装Docker引擎走官方大道别抄小路Ubuntu的默认软件源里有docker.io这个包但它通常是较旧的、由Ubuntu社区维护的版本。为了获得最新的功能、安全更新和最好的兼容性我们强烈建议使用Docker官方提供的存储库进行安装。步骤稍多但一劳永逸。3.1 添加Docker官方APT仓库这一步的目的是告诉你的Ubuntu系统“以后找Docker软件请去Docker官方的仓库下载。”首先安装一些必要的工具让apt可以通过HTTPS协议使用仓库sudo apt 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然后将Docker的APT仓库源添加到系统列表中。这里要注意我们需要根据Ubuntu的代号来配置。Ubuntu 22.04的代号是Jammy Jellyfish。下面的命令会自动获取系统版本并配置正确的仓库地址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$(dpkg --print-architecture)自动获取你的系统架构如amd64, arm64。$(lsb_release -cs)自动获取你的Ubuntu版本代号如jammy。signed-by指定我们刚才添加的GPG密钥文件。最后再次更新APT包索引让系统识别新添加的Docker仓库sudo apt update3.2 安装Docker引擎及相关组件现在可以从官方仓库安装最新的Docker引擎了。我们安装的是一套完整的工具集sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugindocker-ce: Docker社区版引擎核心。docker-ce-cli: Docker命令行工具你用docker命令就是它在工作。containerd.io: 一个行业标准的容器运行时Docker引擎底层会使用它来管理容器生命周期。docker-compose-plugin: 这是Docker Compose V2一个用于定义和运行多容器应用的工具。它现在以插件形式集成在Docker CLI中命令是docker compose注意中间没有横线。安装过程可能会提示你确认磁盘空间输入Y并回车继续。安装完成后Docker服务会自动启动。3.3 验证安装与消除“权限拒绝”错误安装完成后立刻运行一个测试命令是很好的习惯。但如果你直接运行docker version你很可能会看到这样的错误Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.24/version: dial unix /var/run/docker.sock: connect: permission denied这是因为Docker守护进程dockerd是以root用户身份运行的而Docker的Unix套接字文件/var/run/docker.sock默认只有root用户和docker用户组的成员有读写权限。你的普通用户不在docker组里所以被拒绝了。解决方法二选一每次命令前加sudo这是最安全但最麻烦的方式。sudo docker version。将当前用户加入docker组这是一劳永逸的方式也是推荐的做法。sudo usermod -aG docker $USER这条命令将当前用户$USER附加-a到docker组-G docker中。重要提示组权限的变更不会立即生效于当前已登录的会话。你需要完全退出当前用户并重新登录或者开启一个新的终端窗口。简单地关闭再打开同一个终端标签页可能不够最好注销图形界面再登录或者新建一个SSH连接。重新登录后再次运行docker version。这次你应该能看到完整的客户端和服务器版本信息这证明Docker已成功安装并运行。更进一步我们可以运行经典的“Hello World”容器来做最终验证docker run hello-world这个命令会做以下几件事在本地查找名为hello-world的镜像没找到。自动从Docker Hub默认的公共镜像仓库拉取hello-world镜像。基于该镜像创建并启动一个容器。容器运行后打印出一段欢迎信息然后退出。如果你看到“Hello from Docker!”等字样那么恭喜你Docker已经在你的Ubuntu 22系统上完全就绪了。4. 基础配置与优化让Docker真正“好用”起来安装成功只是第一步。默认配置下的Docker用起来可能会遇到镜像下载慢、磁盘空间占用疯长等问题。进行一些基础配置能极大提升日常使用体验。4.1 配置国内镜像加速器直接从Docker Hub拉取镜像对于国内用户来说速度可能非常慢甚至经常超时失败。配置一个国内的镜像加速器是必选项。国内常用的加速器地址有Docker中国官方镜像https://registry.docker-cn.com中科大镜像https://docker.mirrors.ustc.edu.cn阿里云镜像需要登录阿里云控制台进入“容器镜像服务” - “镜像工具” - “镜像加速器”获取为你单独分配的加速地址。这是最快最稳定的选择之一。这里以配置阿里云加速器为例你需要将其中的https://xxxx.mirror.aliyuncs.com替换成你自己的地址首先创建或修改Docker的守护进程配置文件sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json -EOF { registry-mirrors: [https://xxxx.mirror.aliyuncs.com] } EOF注意如果/etc/docker/daemon.json文件已存在此命令会覆盖它。如果你之前有其他配置如日志驱动需要将它们合并到一个JSON对象中。然后重新加载配置并重启Docker服务使更改生效sudo systemctl daemon-reload sudo systemctl restart docker验证加速器是否生效docker info在输出信息中寻找Registry Mirrors部分你应该能看到你刚刚添加的镜像加速器地址。4.2 管理Docker磁盘空间别让“集装箱”堆满仓库Docker很便利但如果你频繁拉取镜像、创建和停止容器它的数据目录/var/lib/docker会像滚雪球一样越来越大占用大量磁盘空间。我们需要定期清理。手动清理命令清理所有已停止的容器、未被任何容器引用的网络、构建缓存和悬空镜像docker system prune执行时会要求你确认输入y。这个命令很安全只会清理那些确定无用的数据。更激进的清理包括未被使用的镜像docker system prune -a这个命令会额外删除所有未被任何容器使用的镜像包括你拉取下来但没在用的请谨慎使用确保没有需要保留的镜像。设置日志轮转防止日志爆盘容器默认的日志驱动json-file会无限制地积累日志文件。我们可以在daemon.json中全局配置日志轮转。编辑/etc/docker/daemon.json加入以下内容如果已有其他配置请合并{ log-driver: json-file, log-opts: { max-size: 10m, max-file: 3 } }这表示每个容器的日志文件最大为10MB最多保留3个文件如container.log,container.log.1,container.log.2。超过后旧文件会被自动删除。修改后同样需要重启Docker服务。4.3 理解Docker的核心操作逻辑配置好后我们来理解几个最核心的命令这比死记硬背命令列表更重要。Docker的操作围绕三个核心概念镜像Image、容器Container、仓库Registry。镜像好比是集装箱的蓝图容器是运行中的集装箱实例仓库则是存放蓝图的仓库如Docker Hub。一个典型的工作流获取镜像docker pull nginx:latest。从仓库拉取NGINX服务器的最新版镜像到本地。pull不是必须的因为run命令如果发现本地没有镜像会自动拉取。运行容器docker run -d -p 8080:80 --name my-nginx nginx。-d: 后台运行detached mode。-p 8080:80: 端口映射将宿主机的8080端口映射到容器的80端口。--name my-nginx: 给容器起个名字否则Docker会分配一个随机名字。nginx: 使用的镜像名。 运行后你就能通过浏览器访问http://你的服务器IP:8080看到NGINX欢迎页了。管理容器docker ps: 查看正在运行的容器列表。docker ps -a: 查看所有容器包括已停止的。docker stop my-nginx: 停止名为my-nginx的容器。docker start my-nginx: 启动一个已停止的容器。docker rm my-nginx: 删除已停止的容器加-f可强制删除运行中的容器。docker logs my-nginx: 查看容器的日志输出。管理镜像docker images: 列出本地所有镜像。docker rmi nginx:latest: 删除指定的本地镜像如果该镜像有容器在使用需先删除容器。掌握这几个命令你就能完成Docker 80%的日常操作了。关键在于理解“镜像-容器”的关系镜像是静态的、分层的模板容器是动态的、可写的实例。你可以基于一个镜像运行无数个容器。5. 进阶一步使用Docker Compose编排多容器应用当你需要运行一个由多个服务组成的应用时比如一个Web应用需要数据库、缓存和自身应用服务器逐个docker run启动每个容器并配置它们之间的网络会非常繁琐。这时Docker Compose我们之前安装的docker-compose-plugin就派上用场了。它允许你使用一个YAML格式的docker-compose.yml文件来定义和运行多个容器。所有服务、网络、卷的配置都在一个文件里通过一条命令就能启动或停止整个应用栈。5.1 编写你的第一个Compose文件假设我们要运行一个简单的WordPress网站它需要WordPress应用和MySQL数据库。创建一个项目目录并在其中创建docker-compose.yml文件version: 3.8 # 指定Compose文件格式版本 services: db: image: mysql:8.0 # 使用MySQL 8.0镜像 volumes: - db_data:/var/lib/mysql # 将数据库数据持久化到名为db_data的卷中避免容器删除后数据丢失 restart: always # 容器退出时总是重启 environment: # 设置环境变量这里用于配置MySQL MYSQL_ROOT_PASSWORD: somewordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: depends_on: # 指明依赖关系wordpress服务会在db服务启动后启动 - db image: wordpress:latest ports: - 8000:80 # 将宿主机的8000端口映射到容器的80端口 restart: always environment: WORDPRESS_DB_HOST: db:3306 # 注意这里使用服务名db作为主机名Compose会自动完成服务发现 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress WORDPRESS_DB_NAME: wordpress volumes: - wp_content:/var/www/html/wp-content # 持久化WordPress的主题和插件等内容 volumes: # 声明在文件底部使用的卷Docker Compose会自动创建和管理它们 db_data: wp_content:这个文件定义了两个服务db和wordpress一个网络Compose会默认创建一个让两个服务能互通以及两个用于数据持久化的卷。5.2 启动、管理与停止整个应用栈在包含docker-compose.yml文件的目录下执行以下命令启动所有服务后台运行docker compose up -d-d参数代表后台运行。Compose会拉取镜像如果本地没有创建网络和卷然后按依赖顺序启动容器。查看运行状态docker compose ps这个命令只显示由当前docker-compose.yml管理的容器比docker ps更清晰。查看服务日志可以查看所有服务的日志或指定某个服务docker compose logs # 查看所有 docker compose logs wordpress # 只查看wordpress服务的日志停止并移除所有容器、网络但保留卷docker compose down数据卷db_data和wp_content会被保留下次up时数据还在。停止并移除所有容器、网络、卷docker compose down -v警告这会删除数据卷所有数据将丢失使用Docker Compose后复杂多容器应用的管理变得极其简单和可重复。配置文件即文档分享给团队成员或部署到新环境时只需要一个docker-compose.yml文件和一条docker compose up -d命令。6. 实战避坑与经验心得理论讲完最后分享几个我实际工作中踩过的坑和总结的经验这些在官方文档里不一定写得那么直白。6.1 容器内的时间与宿主机不一致这是一个非常隐蔽但影响巨大的问题。如果你发现容器里应用日志的时间戳和宿主机差了8个小时或其他时区差大概率是因为容器默认使用UTC时间而你的宿主机是CST上海时间等。解决方法在运行容器时将宿主机的时区文件挂载到容器内。docker run -d -v /etc/localtime:/etc/localtime:ro --name some-container your-image或者在docker-compose.yml中配置services: your-app: image: your-image volumes: - /etc/localtime:/etc/localtime:ro:ro表示以只读方式挂载防止容器内修改宿主机文件。6.2 容器内应用访问宿主机服务在容器内部localhost或127.0.0.1指的是容器自己而不是宿主机。如果你想从容器内访问宿主机上运行的服务比如宿主机上的MySQL需要使用特殊的DNS名称host.docker.internal在Docker Desktop for Mac/Windows中自动支持。在Linux的Docker引擎中可以通过在运行容器时添加--add-host参数来实现docker run --add-hosthost.docker.internal:host-gateway ...或者更通用的方法是直接使用宿主机的真实IP地址。6.3 镜像构建的优化技巧当你开始编写自己的Dockerfile构建镜像时记住以下几点可以显著提升构建速度和镜像质量利用构建缓存Dockerfile中的每条指令都会生成一层镜像层且层是缓存的。把变化最少的指令如安装系统依赖放在前面变化频繁的指令如复制应用代码放在后面。使用.dockerignore文件像.gitignore一样这个文件可以指定在构建上下文你运行docker build的目录中哪些文件不需要发送给Docker守护进程。忽略node_modules、.git、日志文件等可以大大减少构建上下文大小加速构建过程。多阶段构建对于编译型语言如Go, Java可以在一个阶段使用庞大的基础镜像进行编译在另一个阶段使用极小的镜像如alpine只复制编译好的二进制文件。这能生成体积非常小的最终镜像。# 第一阶段构建 FROM golang:1.19 AS builder WORKDIR /app COPY . . RUN go build -o myapp . # 第二阶段运行 FROM alpine:latest COPY --frombuilder /app/myapp /usr/local/bin/myapp CMD [myapp]6.4 不要在生产环境使用最新版Latest标签在docker-compose.yml或Dockerfile中使用image: nginx:latest看似方便但存在风险。latest标签是流动的今天拉取的latest和一个月后拉取的可能是两个不同的版本可能导致应用行为不一致甚至崩溃。最佳实践始终使用明确的版本标签例如image: nginx:1.25-alpine。这确保了部署的一致性和可重复性。你可以通过定期更新版本号来有控制地进行升级。走到这里你在Ubuntu 22上已经拥有了一个配置完善、高效可用的Docker环境。从最开始的系统准备到走官方渠道安装再到配置优化和进阶使用这套流程覆盖了从入门到能应付大多数开发场景的需求。记住Docker是一个工具核心价值在于通过容器化带来环境的一致性和隔离性。多动手运行几个例子尝试构建自己的简单镜像很快你就能体会到它带来的效率提升。如果在使用中遇到其他具体问题善用docker --help、docker logs以及搜索引擎大部分常见问题都有成熟的解决方案。
返回列表