ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Ubuntu安装Docker保姆级教程:从环境配置到容器运行

Ubuntu安装Docker保姆级教程:从环境配置到容器运行 在Linux服务器上装Docker这事说难不难但说简单也不简单。网上教程一搜一大把不是版本老旧就是命令跑一半报错再要么就直接给你扔个官方文档链接让你自己看。尤其对于刚接触Ubuntu、想上手Docker的小白来说光是在“添加源”“GPG密钥”这些词上就能卡住半天。这篇文章我就按我自己实际操作的顺序把在Ubuntu上从零安装Docker的完整流程捋一遍。不绕弯子不整虚的每一步该干什么、为什么这么干、可能会出现什么报错、怎么处理我都会写到。保证你跟着走完能顺利把Docker跑起来并且知道后续基本怎么用。1. 准备工作环境确认与系统更新1.1 先确认你的Ubuntu版本动手之前第一件事是搞清楚你系统具体是什么版本。Docker对系统版本有要求不同Ubuntu版本对应的安装源、内核模块可能不太一样虽然现在Docker官方已经做得比较统一但版本太老的比如16.04那种已经停止维护的确实可能出现兼容性问题。检查版本很简单打开终端输入lsb_release -a或者用更简洁的方式只查看版本号cat /etc/os-release以我自己的服务器为例输出类似这样No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammy目前主流稳定版本是20.04Focal和22.04Jammy如果你用的是24.04Noble也没问题Docker官方支持从Ubuntu 14.04到最新版本的系统。只要你别用那种远古版本正常按照LTW长期支持版本走基本没毛病。另外要注意的是架构问题。大多数情况下你用的是x86_64架构也就是Intel或者AMD处理器但如果你在树莓派、香橙派这类ARM开发板上装命令基本一样只是个别源地址的路径会有细微差别。这个我们在后面安装源的部分再提。1.2 更新软件包索引与系统拿到版本信息之后惯例先把系统软件包索引更新一遍。这一步很多人容易忽略觉得系统能用就不用管但实际上如果软件包索引太旧后面添加Docker源的时候可能会出现签名验证失败或者依赖版本不匹配的问题。sudo apt update这一步会读取/etc/apt/sources.list和/etc/apt/sources.list.d/目录下所有的软件源配置刷新软件包列表。执行过程中你会看到类似这样的输出Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease Get:2 http://security.ubuntu.com/ubuntu jammy-security InRelease ... Reading package lists... Done如果这里出现类似“暂时不能解析域名”或者“无法安全地用该源进行更新”的报错先别往下走大概率是网络问题。常见的原因是无线路由器屏蔽了DNS解析、公司网络有防火墙拦截、或者源地址本身访问不了。处理方式一般是先检查能不能ping通外网ping -c 4 baidu.com如果ping不通优先检查网络连接如果ping得通但apt update报错那就可能是源配置的问题可以考虑把源换成国内镜像源比如阿里云、清华源这个我们在后面也会讲到。更新完之后顺手把系统里已有的软件包也升级一下。这一步看个人需求如果你服务器上有正在跑的重要程序怕升级导致不兼容可以跳过只执行apt update。如果这是一台刚拿到的全新机器建议直接升级sudo apt upgrade -y升级过程可能会比较久取决于你系统安装了多少包和网络速度。期间可能弹出让你选择配置文件如何处理之类的交互窗口一般直接按回车保持默认就行。1.3 卸载旧版本Docker如果有如果你的Ubuntu之前就装过Docker或者你曾经按网上的教程装了一半没装完那在重新安装之前最好先清理一下旧的Docker残留。Docker旧版本Docker 1.x时代的包名是docker、docker-engine、docker.io。假如你系统里有这些旧包直接安装新版本Docker会冲突。查看是否已经安装过Docker相关包dpkg -l | grep -i docker如果有输出就卸载掉sudo apt remove docker docker-engine docker.io containerd runc值得注意的是卸载旧版本Docker不会自动删除/var/lib/docker目录下的镜像、容器、数据卷等数据。如果你确定这些历史数据都不要了可以手动删掉sudo rm -rf /var/lib/docker注意这条命令是白名单级的删除操作会把Docker默认数据目录下的所有内容清空。如果这台机器上有你之前构建的镜像或者正在用的容器数据千万别直接执行先备份我见过不少人因为这条rm命令把自己的生产环境数据清掉的。1.4 安装必要依赖工具在正式安装Docker之前有几个工具是后面必须要用到的。新装的Ubuntu系统不一定自带需要装上sudo apt install -y apt-transport-https ca-certificates curl software-properties-common gnupg lsb-release逐个说一下这些工具的作用apt-transport-https让apt支持通过HTTPS协议访问软件源。Docker官方源走的是HTTPS这个包必须装。ca-certificatesCA证书库用于验证HTTPS连接时服务器的SSL证书是否有效。没有它apt访问HTTPS源会报证书验证失败。curl命令行下的网页请求工具。后面我们要用它下载Docker官方提供的GPG密钥。software-properties-common提供add-apt-repository命令可以用来管理软件源列表。如果你选择使用apt源方式安装Docker后面有讲这个工具会用到。gnupgGNU隐私卫士用来导入和验证GPG密钥。Docker源的签名验证需要它。lsb-release提供lsb_release命令用来识别当前Linux发行版版本信息。有些Docker安装脚本会自动判断系统版本并匹配对应源这个工具就是干这个用的。这几样装完之后准备工作就基本完成了。2. 安装Docker的三种方式选对方法能少走弯路2.1 三种安装方式对比Docker官方提供了三套安装方案分别适用于不同场景。我在不同机器上实践过顺便把它们放在一起对比一下安装方式适用场景优点缺点Docker官方源apt源安装生产环境、常规服务器稳定、可控、可指定版本需要添加GPG密钥和源步骤稍多Docker官方安装脚本快速测试、临时环境一行命令搞定省事脚本来自外部存在一定安全顾虑无法灵活指定版本Docker Desktop仅限桌面版Ubuntu云桌面、开发机带图形界面管理容器直观不适合服务器环境占用资源大依赖虚拟化支持对于绝大多数人来说第一种方式apt源安装是最值得学习掌握的方法没有之一。你想在生产环境装Docker、想装指定版本、想配置国内加速源都离不开这套流程。脚本安装只适合“我这台机器临时用一下无所谓”的场景。2.2 推荐方案使用Docker官方apt源安装先用curl把Docker官方的GPG密钥下载下来并写入系统的keyring目录。这一步是为了验证后面安装的Docker软件包确实来自Docker官方防止被中间人攻击替换成恶意软件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这里有个细节值得说明我以前做这步的时候老教程用的是sudo apt-key add -这种方式但现在Docker官方已经明确不推荐apt-key命令了因为它在系统里是全局生效的一旦一个源使用了某个密钥所有源都会信任它存在安全风险。现在推荐的做法是把密钥下载到/etc/apt/keyrings目录然后在源配置中单独指定这个密钥文件。国内服务器如果在下载GPG密钥时出现超时或者无法解析域名的情况可以考虑使用清华镜像源的密钥。不过先别急大多数情况下官方源都能通可以多试一两次。然后把Docker的源添加到软件源列表里echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release echo $VERSION_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null这个命令看起来复杂拆开看就不慌了。arch$(dpkg --print-architecture)自动识别你的系统架构x86_64会显示amd64ARM服务器会显示arm64。这样不用你手动改。signed-by/etc/apt/keyrings/docker.asc指定用刚才下载的GPG密钥来验证这个源。$(. /etc/os-release echo $VERSION_CODENAME)自动读取你系统的版本代号比如jammy、focal拼接到源地址后面。执行完之后验证一下源文件是否正确写入cat /etc/apt/sources.list.d/docker.list输出应该是类似这样的内容deb [archamd64 signed-by/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu jammy stable确认无误后先更新软件包索引让apt识别到新增的Docker源sudo apt update看到输出中有类似下面这几行内容说明Docker源已经生效Get:5 https://download.docker.com/linux/ubuntu jammy InRelease [48.9 kB] Get:6 https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages [18.9 kB]最后一步就是安装Docker本体及配套组件。官方推荐的安装包组合是sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin逐一说一下这些包是干什么的docker-ceDocker社区版引擎主程序就是核心的守护进程和客户端。docker-ce-cliDocker命令行客户端工具我们平时敲的docker命令全靠它。containerd.io容器运行时管理组件负责实际创建、运行容器。Docker把这一层拆出来之后运行时更稳定也方便单独升级。docker-buildx-pluginBuildx构建插件插件板块用来支持跨平台多架构镜像构建。如果你只是简单使用Docker这个不是必装的但还是建议装。docker-compose-pluginDocker Compose插件用来编排多个容器比如同时启动一个nginx加一个mysql后面你一定会用到。这里安装过程一般不会卡住。如果网络不好下载慢可以考虑先用清华或者阿里云的Docker源替换官方源步骤一样只要把download.docker.com换成镜像地址即可。2.3 备选方案使用Docker官方安装脚本如果你不在乎指定版本就是想赶紧把Docker跑起来用官方脚本是最快的curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh这个脚本会自动检测系统环境、添加源、安装依赖几分钟就全搞完了。我测试过在干净的Ubuntu 22.04上一条龙跑完基本没意外。不过有一点要提醒官方脚本下载自get.docker.com这个域名在部分地区访问不稳定。如果在国内服务器上执行失败了你可以先下载到本机再传到服务器上执行或者直接用apt源那套方案。另一个要注意的是脚本安装默认装的docker-compose-plugin其实不包含传统的docker-compose独立命令。如果你想用docker-compose带横杠这种老命令格式需要额外用一个Python包sudo apt install -y docker-compose但这个版本一般比较老不推荐。新项目一律用docker compose带空格的插件格式。2.4 唯一不推荐的方案Docker DesktopDocker Desktop主要是给macOS和Windows用的它也有Linux版本但只支持Ubuntu的桌面版而且要求系统启用了KVM虚拟化支持。服务器上用Docker Desktop完全没有必要它设计目标是方便开发者在桌面环境里管理和调试容器不是用来跑生产服务的。如果你是在虚拟机里面装的Ubuntu桌面版又恰恰想用图形化管理容器那我建议你别折腾Docker Desktop直接装好Docker引擎之后用Portainer一个开源的Docker图形化管理面板就够了效果类似但轻量得多后面我们可以单独聊这个。2.5 验证安装确认Docker引擎跑起来了装完之后先确认一下版本sudo docker version看到Client和Server两部分都有版本信息输出说明Docker守护进程已经正常工作了。然后跑个Docker官方的Hello World镜像验证能否正常拉取并运行sudo docker run hello-world第一次执行会从Docker Hub拉取hello-world镜像大概几十KB很小拉完后自动运行然后退出输出一段欢迎信息。看到类似以下内容就说明一切正常Hello from Docker! This message shows that your installation appears to be working correctly.这里有个常见疑问为什么docker version能看到Server信息但docker ps就是报错“Cannot connect to the Docker daemon at unix:///var/run/docker.sock”这种情况通常是Docker服务还没启动或者启动失败了。先执行启动命令sudo systemctl start docker sudo systemctl enable dockerstart是启动enable是设置开机自启动。Ubuntu上Docker安装完默认不会设置自启动所以这一步最好做一下。想确认是否设置了开机自启动可以执行sudo systemctl is-enabled docker输出enabled就代表自启动已生效。3. 免sudo执行Docker命令让日常操作不再卡权限3.1 为什么每次都要加sudo细心的你可能已经发现了刚才执行docker命令时前面都加了sudo。这是因为Docker守护进程使用的UNIX套接字默认归属root用户普通用户没有权限访问它。但日常使用中每次都前缀sudo很烦而且如果你写脚本自动化部署sudo还会引入交互式密码验证等一系列麻烦。所以我们要把当前用户加入docker用户组。3.2 添加用户到docker组假设你的当前用户名是demo如果不是把下面的demo换成你自己的用户名sudo usermod -aG docker $USER如果没有设置当前用户用whoami看一下也行。这条命令把当前用户追加到docker组里-aG的a是append追加G是group组意思是不要移除用户已有的其他组信息只追加一个新的docker组。之所以要这样写是因为如果直接用usermod -G docker $USER而不带-a会把用户从其他组中全部踢出来可能导致权限丢失甚至SSH登录异常。改完组之后需要重新登录会话才能生效。最简单的做法是newgrp docker这个命令会切换当前会话的组身份。或者直接退出SSH重新登录一下。注意不是重启系统只要当前终端会话的组信息刷新即可。如果你用的是图形界面登录的用户彻底注销重新登录也行。3.3 验证免sudo是否生效重新登录后不带sudo执行docker ps不报权限错误正常输出容器列表即使列表是空的也会显示一个表头说明配置生效了。注意把用户加到docker组等价于赋予该用户root级别的权限。因为docker组用户可以通过挂载宿主机目录等方式随意操作宿主机文件。如果你是给团队成员开的服务器账号要清楚这个安全边界。3.4 配置镜像加速国内拉镜像不再超时Docker默认的镜像源是Docker Hub在国内访问时通常慢得让人崩溃。拉一个几十MB的小镜像等半天不说还经常中断报错。解决办法是让Docker使用国内镜像加速器。我实践下来比较稳定的是阿里云和网易等几家不过阿里云需要登录后获取专属加速地址建议你按照下面步骤操作。先创建Docker的配置文件目录编辑加速地址sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json -EOF { registry-mirrors: [https://your-mirror.mirror.aliyuncs.com] } EOF把your-mirror.mirror.aliyuncs.com替换成你自己在阿里云容器镜像服务控制台拿到的专属地址。如果你没有阿里云账号也可以网上搜一下目前可用的公共镜像加速地址填入上面的数组中支持填多个用逗号分隔。配置完之后重启Dockersudo systemctl daemon-reload sudo systemctl restart docker然后用后面的操作验证加速是否生效——拉一个稍微大点的公共镜像比如nginx约70MB如果下载速度明显变快说明加速器起作用了。docker pull nginx:latest下载过程中会显示类似这样的进度信息latest: Pulling from library/nginx 6e640d1935d7: Pull complete ... Digest: sha256:... Status: Downloaded newer image for nginx:latest3.5 验证核心命令运行一个nginx容器镜像拉下来后直接跑个容器试试docker run -d --name test-nginx -p 8080:80 nginx这个命令的拆解如下-d让容器在后台运行detached模式不占用当前终端。--name test-nginx给容器起一个名字叫test-nginx。-p 8080:80端口映射“宿主机8080端口”映射到“容器内80端口”。这样你访问服务器的8080端口就等于访问了容器内的nginx服务。nginx指定使用哪个镜像来创建容器。执行之后访问服务器的http://你的服务器IP:8080如果能看到nginx的欢迎页说明Docker已经成功运行并对外提供服务了。查看容器状态docker ps输出中看到STATUS为Up说明容器正在运行、PORTS显示0.0.0.0:8080-80/tcp就证明整个链路是通的。4. 常用命令速查与卸载清理装好只是开始4.1 生命周期管理启停与删除Docker安装好之后日常操作还需要掌握几个核心命令。这里用nginx容器的例子来演示查看所有容器包含已停止的docker ps -a停止一个容器docker stop test-nginx启动一个已有的容器不重新创建docker start test-nginx删除容器docker rm test-nginx注意要删除一个运行中的容器需要先停止它或者用docker rm -f test-nginx强制删除。刚跑起来的nginx容器如果你想删掉重来直接docker rm -f就行。删除镜像docker rmi nginx如果该镜像已经被某个容器使用需要先删除对应容器镜像才能删除成功。镜像和容器的区别可以这样类比镜像好比是一个“操作系统安装光盘”容器是基于这个光盘安装出来的“运行中的系统”。一个光盘可以装出多个系统一个镜像也能创建多个容器它们之间相互隔离、互不影响。4.2 日志查看与进入容器内部查看容器日志排查问题最常用docker logs test-nginxnginx这种服务会输出访问日志你执行后会看到类似这样的内容172.17.0.1 - - [14/May/2024:10:15:46 0000] GET / HTTP/1.1 200 615 - Mozilla/5.0...进入容器内部调试docker exec -it test-nginx /bin/bash-i交互模式保持标准输入流打开。-t分配一个伪终端TTY让你能像在普通终端里一样操作。/bin/bash进入容器后启动bash解释器。进入容器后你的提示符会变成类似root容器ID:/#的样子。注意容器内是一个精简的Linux环境很多命令可能不存在比如没有vim、没有curl需要在容器内用apt先安装才能用。退出容器用exit即可。4.3 查看资源占用容器跑多了之后想知道每个容器占了多少资源docker stats这个命令类似Linux的top命令实时刷新显示各个容器的CPU、内存、网络IO、磁盘IO等指标。按CtrlC退出。4.4 彻底卸载Docker含数据清理如果哪天想换一套容器运行时或者Docker被搞坏了实在修不好那就干净利落地卸载重装。分三步走卸载Docker相关软件包sudo apt purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin删除历史数据和配置sudo rm -rf /var/lib/docker sudo rm -rf /etc/docker删除用户的docker组配置可选sudo groupdel docker卸载完再按文章前面的步骤重新安装即可。注意上述清理操作会删除所有镜像、容器、数据卷和配置文件且过程不可逆。卸载前务必确保你已经备份好需要保留的数据。5. 常见问题与排查方法小白最常踩的5个坑5.1 报错Got permission denied while trying to connect to Docker daemon socket这个问题出现频率最高原因就是没把当前用户加入docker组。回到第3.2节执行sudo usermod -aG docker $USER然后重新登录再执行docker命令。如果加入docker组之后还是报这个错检查一下当前用户是否真的在docker组里groups输出列表里应该包含docker。5.2 报错Failed to connect to the Docker daemon执行docker命令时报“Cannot connect to the Docker daemon”大概率是Docker服务没启动或者启动失败了。先检查服务状态sudo systemctl status docker如果看到红色的failed或者inactive(dead)启动服务sudo systemctl start docker然后再次确认sudo systemctl status docker如果启动失败查看详细日志journalctl -u docker --no-pager -n 50这行命令会显示Docker服务最后50行日志报错原因基本都能在里面找到。常见的原因有daemon.json配置写错导致解析失败、系统内核缺少某个模块等具体问题按日志提示来解决。5.3 报错ERROR: failed to solve: failed to fetch oauth token这个报错通常出现在构建镜像时docker build核心原因是构建过程中需要访问外网获取依赖包网络不通。处理方式有两种。一种是给Docker配置代理。在/etc/systemd/system/docker.service.d/目录下新建一个配置文件sudo mkdir -p /etc/systemd/system/docker.service.d sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf -EOF [Service] EnvironmentHTTP_PROXYhttp://你的代理地址 EnvironmentHTTPS_PROXYhttp://你的代理地址 EOF保存后重启Dockersudo systemctl daemon-reload sudo systemctl restart docker另一种是检查网络环境。如果你的服务器本身在防火墙后面白名单只开放了80和443端口恰好又拉不了镜像那就只能联系运维调整网络策略。5.4 报错无法删除镜像image is being used by container删镜像时报“image is being used by container”说明这个镜像已经被某个容器引用了。先用docker ps -a看看有没有使用该镜像的容器然后删除对应容器再删除镜像。不想要容器的话直接强制删除docker rm -f 容器ID或容器名然后再删除镜像。5.5 镜像加速配置后拉取仍然慢如果你配置了中国大陆镜像加速地址之后docker pull还是慢先确认daemon.json是否真的被Docker读取到了docker info | grep -A 5 Registry Mirrors正常情况会输出你已经配置的加速地址。如果这里显示为空说明Docker没有读到你的配置文件检查一下/etc/docker/daemon.json的文件内容是不是JSON格式合法比如是不是少了逗号、引号有没有成对。如果确认读到配置了但仍然慢那可能是加速地址本身不稳定换个加速地址试试可以多配置几个写成一个数组{ registry-mirrors: [ https://加速地址1, https://加速地址2, https://加速地址3 ] }Docker会按顺序尝试哪个能用就用哪个。6. 写在最后的经验装Docker这件事对于用过一段时间Linux的人来说确实不算什么但对于刚入手Ubuntu的朋友里面每一步都可能藏着坑。我自己就经历过装一半apt源签名错误、装完docker命令找不到、跑容器报端口被占用等各种状况。说实话大部分坑都不是技术难题而是“没人告诉你还有这么个事情需要注意”。有个小习惯我从那之后一直保留着每次在服务器上执行一条不熟悉的命令之前先去看一下它的帮助文档比如docker run --help | head -50这种。花不了几十秒但对于理解这个命令的选项、避免手滑删数据非常有帮助。另外给小白一个建议不用着急去背一堆命令Docker的常用命令翻来覆去就那么一二十条跑几个容器、建几个镜像自然就熟起来了。真要忘了docker --help、docker run --help都在那儿等着你呢。这套流程我在Ubuntu 20.04、22.04以及24.04上都完整跑过步骤基本一致代码没有特殊版本依赖。你按这个顺序装下来基本不会出岔子。装完Docker之后下一站可以试试跑一个Nginx或者MySQL容器先把端口映射、数据目录挂载这些概念搞明白后面玩什么都很顺。
返回列表