资讯动态

Ubuntu 24.04 Docker安装配置实战:镜像加速、MySQL/Redis部署与高频排障

发布时间:2026/9/29 15:45:40 来源:尧图企业网站定制
2026年了Docker在Ubuntu上的安装早就不是什么新鲜事但我在帮同事和读者排查问题的过程中发现真正能把“装好、配置好、跑稳”一条龙走完的人并不多。这篇指南以Ubuntu 24.04 LTS为基准22.04、26.04的LTS版本命令基本通用覆盖系统准备、Docker引擎安装、镜像加速、MySQL和Redis实战再到高频错误排查的完整链路。适合第一次在Linux上装Docker的人也适合部署微服务时被网络问题卡住的老手。照着往下走绝大部分坑都能提前绕开。1. 安装前的准备系统选型与依赖排查1.1 Ubuntu版本怎么选LTS还是滚动版截至2026年年中Ubuntu的LTS版本有两个值得关注24.04 LTS2024年4月发布和26.04 LTS2026年4月发布。我的建议是生产环境优先选24.04 LTS因为它的软件源、内核、驱动生态已经被两年多的更新打磨得很稳定对于新功能尝鲜场景26.04 LTS也可以上但会相对激进一些。Docker官方apt仓库对这两个版本都有对应的源安装命令差异不大。至于从哪里下载镜像文件网上搜“ubuntu下载”会看到很多渠道。我建议去Ubuntu官网下载ISO或者用权威的开源镜像站。下载时注意区分桌面版Desktop和服务器版Server桌面版带图形界面适合个人开发服务器版更精简安装Docker后占用资源更少。虚拟机环境里如果只是想学习和测试桌面版也够用比如那串经常被搜索的“ubuntu 22.04.5 desktop amd64.iso”就是VirtualBox或VMware里最常用的镜像之一。如果是在虚拟机里装Ubuntu再装Docker需要提前确认两件事一是虚拟机的CPU虚拟化要开启VMware里叫“虚拟化 Intel VT-x/EPT”VirtualBox里是“启用嵌套分页”不然后续跑Docker Desktop会卡在“virtualization support not detected”这类错误上二是给虚机分配至少2GB内存否则编译和跑容器时会频繁OOM。1.2 更新系统与基础依赖别跳过这步拿到一台全新Ubuntu后我习惯先做一次完整的系统更新把内核和软件包统一到最新状态。这一步很多人觉得浪费时间但跳过之后往往会在安装时遇到“依赖库版本过旧”或者“GPG签名校验失败”这类莫名其妙的问题。执行命令sudo apt update sudo apt upgradeapt update是刷新软件包索引apt upgrade是真正升级已有软件包。升级过程中如果提示内核更新问你要不要重启我会选择重启一次再继续装Docker——因为新内核和旧内核的模块差异可能影响后续容器网络的iptables表现。随后把三个基础工具装上ca-certificates、curl、gnupg。ca-certificates保证HTTPS下载的证书链可信curl用来下载Docker官方GPG密钥gnupg用来导入和管理这个密钥。少了任何一个后面执行添加仓库的命令都会报错比如curl: (60) SSL certificate problem或者gpg: command not found。sudo apt install -y ca-certificates curl gnupg另外如果这台机器是拿来当开发机用我建议顺手把SSH服务和中文输入法也配置好。搜“ubuntu ssh无法连接”的人很多大部分case就是openssh-server没装或者防火墙放行没做搜“ubuntu中文输入法怎么设置”的通常是装了搜狗输入法后fcitx没设成默认。这些和Docker没有直接关系但挂在同一台机器上会影响你后续的操作效率。装好Docker再回来折腾这些会更省心。2. Docker引擎安装三种方式的选型对比2.1 官方apt仓库安装法推荐装Docker引擎最靠谱的永远是官方apt仓库没有之一。很多人搜“docker安装教程”搜到的都是古老的一键脚本方式但生产环境我强烈建议走apt仓库版本可控、升级方便、安装过程可审计。先导入Docker官方的GPG密钥curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg这条命令把Docker公钥下载、解包成二进制格式放到系统keyrings目录。如果跳过这步后面apt update会把Docker源里的key识别为不受信任的第三方源直接拒绝读取。接着写仓库文件。我建议把仓库地址写进/etc/apt/sources.list.d/docker.list尽量不动主源文件方便以后删除或迁移echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release echo $UBUNTU_CODENAME) stable | sudo tee /etc/apt/sources.list.d/docker.list这里用了$(. /etc/os-release echo $UBUNTU_CODENAME)来动态取版本代号不管你是24.04还是26.04源都是对的不用手改。如果你还在用22.04也能自动识别成jammy。更新索引后安装sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin注意这几个包各有用处docker-ce是Docker核心引擎服务docker-ce-cli是命令行工具containerd.io是底层容器运行时负责镜像拉取和容器生命周期管理docker-buildx-plugin提供新型构建工具docker-compose-plugin提供docker compose子命令。我一次装齐避免后面临时要用还得补装。2.2 脚本一键安装与二进制安装的取舍官方其实提供了一个一键安装脚本curl -fsSL https://get.docker.com | sudo sh。这个方式在测试环境非常爽一条命令就能起来而且它会自动帮你配好apt源。但有两个问题一是脚本执行内容对新手不透明你不知道它到底改了哪些系统文件出了问题难以恢复二是脚本默认装的版本可能不是你的目标版本升级策略也需要自己掌握。二进制安装则是把Docker各组件直接解压到/usr/local/bin或/opt/docker下自己写systemd服务。这种方式在无法访问外网的内网环境很实用但维护成本高需要手动管理版本和启动脚本。我的结论是网上那些“docker安装教程”里的脚本方式只能用来快速验证正经环境都该用2.1的apt仓库路线。装完后把服务设为开机自启并立即启动sudo systemctl enable --now docker然后验证版本docker version这段输出里Client和Server两部分都能正常显示才说明daemon起来了。如果只看到Client没有Server多半是服务没启动成功去后面第6章的对症排查。2.3 安装后的验证与版本确认除了docker version我还会跑一个hello-world来验证镜像拉取、容器运行、日志输出整条链路通不通sudo docker run hello-world看到“Hello from Docker!”就说明一切正常。这一步如果卡在pull阶段不动通常不是Docker装坏了而是没法访问Docker Hub——需要配镜像加速这就是下一章的内容。另外跑一条docker info看一下运行环境。重点看两行Storage Driver显示overlay2这是目前最推荐的文件驱动Server Version显示具体的引擎版本号如果你习惯用GitHub Release里的新特性可以对照这个版本号判断是否要手动升级。3. 镜像加速与Docker Desktop选型3.1 镜像加速国内拉取提速的配置方法Docker默认从Docker Hub拉镜像国内网络下经常遇到超时、断流。解决办法是配置镜像加速器。操作很简单编辑/etc/docker/daemon.json{ registry-mirrors: [https://xxx.mirror.example.com] }把xxx.mirror.example.com替换为你当前实际可用的公共镜像加速地址。需要注意的是这些年公共镜像站换了一批又一批使用前最好自己实测一下改完后执行docker pull拉取一个小镜像验证速度即可。修改完daemon.json要重启Docker才生效sudo systemctl restart docker配置了加速器后Docker的镜像拉取会先尝试从镜像站走失败才回源Docker Hub所以在容器里看到的镜像URL一般还是官方的不用担心兼容性问题。3.2 存储驱动与日志配置避免磁盘被容器日志塞满镜像加速只是daemon.json的一种配置我在生产环境里还会同时把日志策略和存储驱动写进去。最常遇到的问题是容器跑久了/var/lib/docker里的json.log日志文件会无限膨胀直接把磁盘吃满。搜“docker网络不通”的人有不少其实是栽在这一条上。建议在daemon.json里显式限制单容器日志大小和文件个数{ data-root: /var/lib/docker, log-driver: json-file, log-opts: { max-size: 20m, max-file: 5 } }max-size20m表示单个日志文件最大20MBmax-file5表示日志文件最多保留5个达到上限后自动轮转、删除最早的日志。这个配置对任何长期运行的容器都推荐做上尤其是数据库和业务API容器。>docker pull ubuntu:24.04 docker pull mysql:8.0 docker pull redis:7不加tag默认拉latest。拉取的过程会看到很多层的下载进度这说明镜像是由只读镜像层叠加而成这也是Docker比传统虚拟机更省空间的核心原因——多个镜像可以共享相同的底层layer。给镜像打tag是日常操作docker tag mysql:8.0 registry.example.com/mysql:8.0tag搞乱了或者想清理无用镜像用docker rmi和docker image prune。我一般会定时执行docker image ls docker image prune -f后者会把所有dangling镜像没有tag的悬空镜像清掉腾出不少空间。注意别用docker system prune -a它会把所有没在用的镜像、容器、卷全删掉新手容易把还要用的开发镜像一起清走。合成镜像和构建过程相关的经验跑过一次就知道清理这一步必须克制。4.2 容器生命周期run、start、stop与常用参数容器是镜像的运行时实例。第一个run命令通常写成这样docker run -d --name myapp -p 8080:80 -v /data:/app/data nginx参数拆开解释-d表示后台运行--name指定容器名-p 8080:80表示把宿主机的8080端口转发到容器的80端口-v把宿主机的/data目录挂载到容器内的/app/data目录。这里最容易踩的坑是端口映射写反把宿主机和容器端口搞颠倒了导致访问不到。我习惯的记法是左边永远写宿主机端口右边写容器内端口。容器启停和删除docker start myapp docker stop myapp docker rm myapp注意docker rm只能删已经停止的容器强制删运行中的加-f。另一个我常用的参数是--restartalways建议加在长期运行的容器上让Docker在宿主机重启后自动拉起容器省得每次开机手动start。进入运行中的容器调试docker exec -it myapp bash容器里没有bash的换成sh。这里的-it两个参数分别代表交互模式和分配伪终端缺一都进不去交互shell。4.3 数据卷与挂载让容器数据不丢容器本身是无状态的一旦docker rm容器里产生的文件就全没了。所以凡是需要持久化的数据数据库文件、上传目录、日志目录都要挂载出来。Docker提供两种方式第一种是绑定挂载直接挂宿主机的某个路径适合配置文件、代码目录。缺点是路径耦合换机器要改路径。第二种是具名卷由Docker管理目录用docker volume create创建或者直接-v mysql-data:/var/lib/mysqlDocker会自动帮你建卷。这种方式更适合存放数据库这类重要数据备份恢复也方便docker volume ls就能看到所有卷。我在实际部署MySQL时一定会给数据目录挂具名卷同时把配置文件也用bind mount挂进去这样既能持久化又能按需改配置。第5章会给出完整命令。5. 实战篇用Docker跑起MySQL和Redis5.1 部署MySQL 8.0字符集、远程连接与数据持久化先建一个具名卷再启动MySQL 8.0容器docker volume create mysql-data docker run -d --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDYourStrongPass123 \ -e TZAsia/Shanghai \ -v mysql-data:/var/lib/mysql \ -v /etc/mysql-conf:/etc/mysql/conf.d \ mysql:8.0启动后过几秒再进入容器检查状态docker ps docker exec -it mysql8 mysql -uroot -p输入密码后可以先看字符集SHOW VARIABLES LIKE character%;如果看到utf8mb4相关说明默认配置正常。MySQL 8本身默认就是utf8mb4但8.0之前的老库需要手动指定具体可以在挂载的/etc/mysql-conf/my.cnf里写[mysqld] character-set-serverutf8mb4 collation-serverutf8mb4_0900_ai_ci远程连接常见的坑还有两点一是授权问题MySQL 8默认root只允许localhost登录要远程访问需要先建专用账号并授权二是防火墙要放行宿主机的3306端口。我建议更安全的做法是不要把数据库端口暴露到公网而是通过应用层访问或内网网络隔离。另外配合容器的实践我还会同时起一个phpMyAdmin或Adminer容器来管理数据库。管理容器用同一自定义网络与mysql8互通实现可视化操作比命令行折腾授权舒服得多。5.2 搭建Redis主从一份配置搞定Redis主从是高频需求。先启动主节点docker run -d --name redis-master -p 6379:6379 redis:7 redis-server --appendonly yes这里--appendonly yes开启AOF持久化。然后启动从节点指定主节点地址docker run -d --name redis-slave -p 6380:6379 redis:7 \ redis-server --replicaof 主节点IP 6379 --appendonly yes注意主节点IP这里如果你把两个容器放在同一个自定义网络可以直接写容器名redis-masterDocker网络会做DNS解析。所以更好的做法是先建网络docker network create redis-net docker network connect redis-net redis-master docker network connect redis-net redis-slave从节点命令就可以改写成docker run -d --name redis-slave --network redis-net -p 6380:6379 redis:7 \ redis-server --replicaof redis-master 6379 --appendonly yes验证主从状态docker exec -it redis-master redis-cli INFO replication docker exec -it redis-slave redis-cli INFO replication主节点输出里的role:master和connected_slaves:1从节点输出里的role:slave和master_link_status:up就说明主从已建立。这里多说一句主从复制只是数据冗余不具备自动故障转移能力真要高可用还得上哨兵或集群模式但那套复杂度是另一个话题了。5.3 用Docker Compose编排多容器当容器多起来一条条docker run很容易失控这时用Docker Compose。Compose本质是用一个YAML文件声明整个应用栈一条docker compose up -d拉起所有服务。以“docker部署微服务项目”场景为例我写一个包含MySQL、Redis和一个简单API的compose文件services: mysql8: image: mysql:8.0 container_name: compose-mysql8 restart: always environment: MYSQL_ROOT_PASSWORD: YourStrongPass123 TZ: Asia/Shanghai ports: - 3306:3306 volumes: - mysql-data:/var/lib/mysql - ./mysql-conf:/etc/mysql/conf.d redis: image: redis:7 container_name: compose-redis restart: always ports: - 6379:6379 command: redis-server --appendonly yes api: image: your-api-image:latest container_name: compose-api restart: always depends_on: - mysql8 - redis ports: - 8080:8080 environment: DB_HOST: mysql8 REDIS_HOST: redis SPRING_PROFILES_ACTIVE: prod volumes: mysql-data:这里面的关键点是depends_on声明了启动顺序等MySQL和Redis先启动再起应用容器——但要注意Compose的depends_on只保证容器启动顺序不代表数据库初始化完成所以很多项目会在应用里做重试等待。启动和运维命令docker compose up -d docker compose ps docker compose logs -f docker compose downdown会停掉并删除容器但不会删除卷数据还在。要连同卷一起删是down -v这个命令要慎用。6. 高频问题排查与避坑实录6.1 Docker服务启动失败与权限报错先解决权限问题。如果你执行docker ps报“Got permission denied”说明当前用户不在docker组里。执行sudo usermod -aG docker $USER然后注销重新登录或者执行newgrp docker。这背后的机制是Docker客户端与服务端通过Unix socket通信用户必须加入docker组才有权限访问这个socket。不加入docker组每次都得加sudo时间长了很容易因为sudo权限问题在脚本里踩坑。服务起不来的场景先看状态systemctl status docker journalctl -u docker -n 50常见诱因有三个一是containerd坏了或者端口冲突重启containerd再看二是/var/lib/docker权限被改过改成root用户可读写即可三是内核iptables模块没加载Docker在创建NAT规则时直接失败这种情况需要检查内核是否启用了netfilter相关模块。还有一种很隐蔽的情况系统里有老版本docker或podman残留apt装新版时会遇到版本冲突提示“docker-ce : Depends: docker-ce-cli but it is not going to be installed”这类。我的习惯是碰到这类依赖报错先sudo apt --fix-broken install再重新安装。6.2 容器网络不通网段冲突与DNS问题“docker网络不通”是搜索热词但原因往往各不相同。最常见的是宿主机局域网网段和docker0默认网段172.17.0.0/16撞了。比如路由器分配的是192.168.x.x还好一旦内网用了172.17.x.x段容器访问外面就会路由错乱。解决办法是改docker0的网段在daemon.json里加{ bip: 10.10.0.1/24 }重启后docker0变成10.10.0.1就避开冲突了。容器访问外网出问题的另一个原因是DNS配置。容器默认DNS指向宿主机的systemd-resolved但某些情况下systemd-resolved会拒绝容器的查询。此时可以给容器加--dns参数或者全局在daemon.json里设置{ dns: [8.8.8.8, 8.8.4.4] }还有一类“ping不通但服务能通”的情况很多基础镜像里没装ping和curl你直接docker exec进去执行ping命令当然报错找不到命令。这不代表网络真的不通用curl通就说明没问题。6.3 资源与系统联动问题磁盘爆满与数据清理容器跑一段时间后/var/lib/docker的体积会快速增长来源有日志膨胀、镜像层残留、孤儿卷三类。先用docker system df看空间占用分布docker system df输出里列明镜像、容器、卷各占多少。清理手段按危险程度排序docker system prune清理停止的容器、悬空镜像、无用网络日常推荐docker image prune -a清理所有未被容器使用的镜像慎用docker volume prune清理孤儿卷务必谨慎卷里有数据库数据就误删了最后再补充两个容易忽视的点。一是时区容器默认是UTC日志时间比北京时间慢8小时解决办法是启动时加-e TZAsia/Shanghai或者挂载/etc/localtime。二是虚拟机里的Ubuntu重启后Docker网络可能失效可以执行systemctl restart docker让网桥重建。我的习惯是把上面几条写成一个“容器日常巡检”清单每周看一次docker system df确认日志轮转配置存活用docker ps --format检查有没有意外停止的容器。做好这三件事基本能把安装和使用过程中的大坑都挡在门外。最后分享一点我的个人体会。Docker安装本身不难难的永远是两个字习惯。配好镜像加速、日志轮转、数据持久化这三个习惯你的容器环境会省心很多反过来图省事跳过任何一步事后多半要花双倍时间回来填坑。另一个小建议是不要在网上一搜到一键脚本就立刻执行先搞清楚它改了什么再动手——这在2026年如此以后更是如此。希望这份指南能让你少走几次弯路。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑