ARTICLE DETAIL

资讯详情

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

Docker新手入门指南:从Ubuntu安装到docker-compose部署WordPress

Docker新手入门指南:从Ubuntu安装到docker-compose部署WordPress 简介这份PDF面向零基础或缺乏容器化经验的开发者与运维人员系统梳理Docker从概念到实战的完整入门路径。内容涵盖容器与虚拟机的差异对比、Ubuntu环境下的安装与用户组配置、镜像与容器生命周期管理、调试日志技巧并以部署WordPress为例演示docker-compose.yml编写与服务启动同时讲解数据卷与绑定挂载两种持久化方案及容器安全最佳实践。资源包共1个PDF文件大小约760KB篇幅紧凑、结构清晰适合作为案头速查手册。目前已有1057人学习说明其内容经过一定规模读者验证。读者可借此快速搭建本地Docker环境掌握常用命令与排错思路并通过WordPress实战理解多容器编排流程为后续进阶学习打下基础。1. 从一台干净的 Ubuntu 说起这份 Docker 入门指南到底能帮你省掉哪些弯路如果你手上有一台刚装好的 Ubuntu想跑个 Nginx 或者 WordPress传统做法是apt install一堆依赖然后开始跟版本冲突、端口占用、配置文件路径搏斗。这份《Docker 新手入门指南从零开始掌握容器化技术》解决的正是这个场景——它不讲空泛的容器哲学而是从卸载旧版本、配软件源、装 Docker Engine 一路写到用 docker-compose 起一套 WordPress中间穿插镜像管理、容器生命周期、数据卷和绑定挂载。适合两类人一是刚接触容器化技术、需要一份能照着敲的实操手册的开发者二是运维转云原生、想把 Docker 安装教程和 docker-compose 编排一次性跑通的从业者。它不覆盖 Kubernetes也不深入网络模式但把单机容器化最常用的 80% 操作讲透了。2. 安装与权限配置Ubuntu 上把 Docker Engine 装干净2.1 为什么不用 apt 自带的 docker.ioUbuntu 官方源里的docker.io版本通常落后于 Docker 官方仓库而且包名和依赖关系跟官方docker-ce不一致。常见做法是先把旧版本清掉再通过 Docker 官方 GPG key 和软件源安装。这份指南给的就是官方仓库路线好处是后续docker compose插件、docker buildx都能一起装上不用单独折腾。另一个容易被忽略的点是containerd和runc的版本——官方源会一并管理避免手动装出现版本错配。2.2 安装命令逐段拆解# 卸载可能存在的旧版本避免包冲突 sudo apt-get remove docker docker-engine docker.io containerd runc # 更新索引并安装证书、curl、gnupg sudo apt-get update sudo apt-get install ca-certificates curl gnupg # 创建 keyrings 目录权限 0755 sudo install -m 0755 -d /etc/apt/keyrings # 下载 Docker 官方 GPG key 并解码存放 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \ sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod ar /etc/apt/keyrings/docker.gpg # 写入软件源arch 和 VERSION_CODENAME 自动取当前系统值 echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] \ https://download.docker.com/linux/ubuntu \ $(. /etc/os-release echo $VERSION_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null # 安装 Docker Engine、CLI、containerd 以及 buildx、compose 插件 sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io \ docker-buildx-plugin docker-compose-plugin # 验证拉取 hello-world 并运行 sudo docker run hello-world逻辑说明install -m 0755 -d确保 keyrings 目录存在且权限正确否则gpg --dearmor会因目录不存在报错。$(dpkg --print-architecture)和$(. /etc/os-release echo $VERSION_CODENAME)是让软件源自动适配当前架构和 Ubuntu 代号避免手写jammy或focal写错。最后一步docker run hello-world不只是验证安装它还会检查 Docker daemon 是否在运行、能否拉取镜像、容器能否正常启动——三个环节一次过。参数说明docker-ce是社区版引擎docker-ce-cli是命令行客户端containerd.io是底层容器运行时docker-buildx-plugin提供多平台构建能力docker-compose-plugin让你能用docker compose而不是老式的docker-compose二进制。2.3 把当前用户加入 docker 组装完之后每次敲docker都要加sudo原因是/var/run/docker.sock默认属于 root。把用户加入 docker 组就能免 sudo# 创建 docker 组已存在会提示忽略即可 sudo groupadd docker # 将当前用户加入 docker 组 sudo usermod -aG docker $USER # 刷新当前 shell 的组信息或者直接退出重新登录 newgrp docker # 验证不加 sudo 运行 hello-world docker run hello-world逻辑说明usermod -aG的-a是追加不加-a会把你从其他附加组里踢出去。newgrp docker只对当前终端生效新开的终端会自动读取新组。如果newgrp后仍然提示权限拒绝检查/var/run/docker.sock的属组是不是 docker常见情况是 Docker 服务没重启导致 socket 属组没更新。注意把用户加入 docker 组等同于给了该用户 root 级权限因为容器可以挂载宿主机根目录。生产环境里更稳妥的做法是用 rootless 模式或 sudo 白名单但开发机上加组是常规操作。3. 镜像与容器生命周期把 docker run 的参数吃透3.1 镜像管理pull、images、rmi、build镜像操作是日常最高频的动作。这份指南列了四条命令但实际用起来有几个细节值得展开# 拉取 nginx 最新版镜像 docker pull nginx:latest # 查看本地镜像含镜像 ID、标签、大小 docker images # 删除指定镜像 docker rmi nginx:latest # 根据当前目录的 Dockerfile 构建镜像打标签 myapp:v1 docker build -t myapp:v1 .逻辑说明docker pull nginx:latest里的latest是默认标签但生产环境不建议用latest因为每次拉取可能拿到不同版本导致“昨天还能跑今天挂了”的玄学问题。docker images输出里的 IMAGE ID 是短 ID删除时可以用短 ID 也可以用仓库:标签。docker rmi如果镜像被容器引用会报错需要先删容器或加-f强制。docker build最后的.是构建上下文路径不是 Dockerfile 路径——Dockerfile 默认在上下文根目录用-f可以指定其他位置。参数说明-t给镜像打标签格式是名称:版本--no-cache在构建时禁用缓存排查“改了代码但镜像没变”时用--platform指定目标架构比如在 x86 机器上构建 arm64 镜像。3.2 容器生命周期run、ps、stop、start、rm容器生命周期命令看似简单但docker run的参数组合是新手翻车最多的地方# 后台运行 nginx把宿主机 80 映射到容器 80命名 my-nginx docker run -d -p 80:80 --name my-nginx nginx # 查看运行中的容器 docker ps # 查看所有容器包括已停止的 docker ps -a # 停止、启动、删除容器 docker stop my-nginx docker start my-nginx docker rm my-nginx逻辑说明-d让容器在后台运行不加的话终端会被前台进程占住。-p 80:80是宿主机端口:容器端口顺序反了就连不上。--name给容器起名不起名的话 Docker 会随机分配一个名字后续操作得先docker ps查 ID。docker stop发送 SIGTERM 并等待 10 秒超时再 SIGKILLdocker rm只能删已停止的容器运行中的要加-f。参数说明-it组合用于交互式容器-i保持 stdin 打开-t分配伪终端--restart控制重启策略always是开机自启unless-stopped是除非手动停止否则自启-e注入环境变量WordPress 案例里大量用到。3.3 调试与日志exec、logs、inspect容器出问题时这三个命令是主要排查手段# 进入容器终端bash 不存在时换 sh docker exec -it my-nginx bash # 查看容器日志-f 持续输出--tail 只看最后 N 行 docker logs -f --tail 100 my-nginx # 查看容器详细信息输出 JSON docker inspect my-nginx逻辑说明docker exec是在运行中的容器里开一个新进程容器停了就用不了得用docker start先起来。docker logs读的是容器主进程的 stdout/stderr如果应用把日志写到文件里logs 看不到得 exec 进去 cat。docker inspect输出很长常用--format过滤比如docker inspect --format{{.NetworkSettings.IPAddress}} my-nginx直接拿 IP。参数说明exec的-it和run一样logs的--since按时间过滤--timestamps加时间戳inspect的-f或--format用 Go 模板语法提取字段。提示docker exec进去之后做的修改不会保存到镜像容器删除就没了。要持久化得改 Dockerfile 重新构建或者用数据卷挂载。4. 用 docker-compose 部署 WordPress多容器编排的第一课4.1 为什么 WordPress 适合当第一个 compose 项目WordPress 需要两个服务MySQL 数据库和 WordPress 本身。用docker run起两个容器再手动连网络、传环境变量也能跑但 compose 用一个 YAML 文件就把依赖关系、网络、卷全声明了。这份指南给的 compose 文件是经典的最小可用配置适合理解services、volumes、depends_on、environment四个核心字段。4.2 docker-compose.yml 逐字段拆解version: 3 services: db: image: mysql:8.0 volumes: - db_data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: rootpass MYSQL_DATABASE: wordpress MYSQL_USER: wpuser MYSQL_PASSWORD: wppass wordpress: image: wordpress:latest ports: - 8000:80 environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_USER: wpuser WORDPRESS_DB_PASSWORD: wppass depends_on: - db volumes: db_data:逻辑说明db服务用mysql:8.0镜像volumes把命名卷db_data挂到/var/lib/mysql这样容器删了数据还在。environment里的四个变量是 MySQL 镜像约定的初始化参数MYSQL_DATABASE会自动建库MYSQL_USER和MYSQL_PASSWORD会自动建用户并授权。wordpress服务把宿主机 8000 映射到容器 80WORDPRESS_DB_HOST写db是因为 compose 默认给所有服务建一个网络服务名就是 DNS 名。depends_on只保证启动顺序不保证 MySQL 就绪——WordPress 启动时如果 MySQL 还没初始化完会报连接失败但刷新几次就好了。参数说明version: 3是 compose 文件格式版本新版 Docker 可以省略ports的引号建议保留避免 YAML 把8000:80解析成时间volumes顶层声明命名卷服务里引用时写卷名:容器路径。4.3 启动、验证与常见调整# 在 docker-compose.yml 所在目录执行后台启动 docker compose up -d # 查看服务状态 docker compose ps # 查看某个服务的日志 docker compose logs -f wordpress # 停止并删除容器、网络但保留卷 docker compose down # 停止并删除容器、网络、卷 docker compose down -v逻辑说明docker compose up -d会按依赖顺序创建网络、卷、容器。docker compose ps显示的是 compose 项目下的容器比docker ps更聚焦。docker compose down默认不删卷数据还在加-v才删卷这个参数用之前想清楚删了就找不回来。访问http://localhost:8000就能看到 WordPress 安装界面。如果页面报“Error establishing a database connection”先docker compose logs db看 MySQL 是否初始化完成再docker compose logs wordpress看连接参数。常见原因是 MySQL 8.0 的认证插件和旧版 WordPress 不兼容但wordpress:latest已经处理了这个问题。注意compose 文件里的密码是明文本地开发无所谓放到版本控制里之前记得改成环境变量文件.env并加入.gitignore。5. 数据持久化与安全卷、绑定挂载和非 root 运行5.1 数据卷与绑定挂载的选型Docker 的数据持久化有两种方式命名卷和绑定挂载。命名卷由 Docker 管理存在/var/lib/docker/volumes/下适合数据库这类不需要直接访问文件的场景。绑定挂载把宿主机目录直接映射进容器适合开发时改代码即时生效。# 命名卷创建 my-vol挂到容器的 /app docker volume create my-vol docker run -d \ --name devtest \ -v my-vol:/app \ nginx:latest # 绑定挂载把当前目录的 html 挂到 nginx 的网页目录 docker run -d \ --name devtest \ -v $(pwd)/html:/usr/share/nginx/html \ nginx:latest逻辑说明-v my-vol:/app里my-vol是卷名Docker 会自动创建-v $(pwd)/html:/usr/share/nginx/html里宿主机路径必须是绝对路径$(pwd)展开当前目录。绑定挂载的权限问题很常见——容器内进程的 UID 和宿主机文件属主不一致时会写不进去解决办法是-u指定 UID 或者调整宿主机目录权限。参数说明docker volume ls列出所有卷docker volume inspect my-vol看卷的挂载点docker volume rm my-vol删卷。绑定挂载加:ro可以只读挂载比如-v $(pwd)/config:/etc/nginx/conf.d:ro。5.2 非 root 运行与最小化镜像这份指南的安全部分给了两条原则最小化镜像和非 root 运行。Dockerfile 示例用node:18-alpine做基础镜像USER node切换非 root 用户FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --onlyproduction USER node CMD [node, server.js]逻辑说明alpine镜像体积只有几十 MB比node:18小一个数量级但 alpine 用的是 musl libc某些依赖 glibc 的 npm 包会出问题构建时报错就换node:18-slim。npm ci比npm install更适合 CI 环境它严格按package-lock.json安装不会改锁文件。USER node必须在COPY和RUN之后否则后续文件属主会变成 node可能导致权限问题。参数说明WORKDIR创建并切换目录后续COPY和RUN都在这个目录下COPY package*.json ./先只拷依赖清单利用 Docker 层缓存代码改了不用重装依赖--onlyproduction跳过 devDependencies。提示docker scan可以扫描镜像漏洞但需要登录 Docker Hub。替代方案是trivy image 镜像名本地跑不需要账号。6. 排查清单与进阶路径那些文档没写的翻车点6.1 五条血泪踩坑记录现象docker run hello-world报Cannot connect to the Docker daemon。原因Docker 服务没启动或者当前用户不在 docker 组且没加 sudo。 解决sudo systemctl start docker启动服务sudo systemctl enable docker设开机自启权限问题按第 2.3 节加组后重新登录。现象docker pull卡住或超时。原因默认镜像仓库在国内访问不稳定。 解决配置镜像加速器编辑/etc/docker/daemon.json加registry-mirrors然后sudo systemctl restart docker。注意加速器地址会失效用之前先确认可用性。现象docker compose up后 WordPress 报数据库连接错误。原因MySQL 8.0 初始化需要时间WordPress 启动太快连不上或者WORDPRESS_DB_HOST写成了localhost而不是服务名db。 解决等几十秒刷新页面检查 compose 文件里 host 是否为服务名docker compose logs db确认 MySQL 是否 ready。现象绑定挂载的目录在容器里看不到文件。原因SELinux 或 AppArmor 拦截或者宿主机路径写成了相对路径。 解决Ubuntu 上检查 AppArmor 状态挂载路径用$(pwd)展开成绝对路径SELinux 系统加:z或:Z标签。现象docker build时npm install失败报网络错误。原因构建容器内的 DNS 配置和宿主机不一致或者基础镜像的包管理器源不可达。 解决在 Dockerfile 里换源或者构建时加--networkhost让构建容器用宿主机网络。6.2 从单机到编排的进阶路线这份指南最后给了学习路径官方文档、Play with Docker 实验环境、网络模式、Compose、Kubernetes、CI/CD。按我的经验顺序应该是先把docker run和docker compose用熟再碰网络模式。bridge 模式是默认host 模式让容器直接用宿主机网络性能好但端口冲突风险高none 模式适合完全隔离的场景。Kubernetes 不用急着上单机 compose 能跑通三五个服务之后再理解 Pod、Service、Deployment 会顺很多。验证自己是否真的掌握了可以试一个具体技巧用docker compose起一套 WordPress然后故意把db服务的卷删掉观察数据丢失的过程再用绑定挂载把 WordPress 的wp-content目录映射到宿主机改主题文件即时生效。这一套走下来数据卷和绑定挂载的区别就不用背了。从那以后我每次写 compose 文件都强制先跑一遍docker compose config检查语法再up -d最后logs -f盯一分钟——这个习惯帮我省掉了至少三次“以为起来了其实在反复重启”的排查时间。希望帮到你。本文还有配套的精品资源点击获取
返回列表