Docker 容器化入门实战:从镜像到部署的最短路径

举报
yd_237615889 发表于 2026/09/06 21:19:04 2026/09/06
【摘要】 Docker 容器化入门实战:从镜像到部署的最短路径"在我机器上是好的啊!"——这句话背后,是新员工装环境装一整天、测试环境和生产环境行为不一致、依赖冲突互相打架。容器化的目标只有一个:把应用和它的运行环境打包成一个标准件,在任何装了 Docker 的机器上行为完全一致。这篇不讲容器底层原理(namespace、cgroup 有机会单独写),专注一条最短实战路径:核心概念 → 常用命令 → ...

Docker 容器化入门实战:从镜像到部署的最短路径

"在我机器上是好的啊!"——这句话背后,是新员工装环境装一整天、测试环境和生产环境行为不一致、依赖冲突互相打架。容器化的目标只有一个:把应用和它的运行环境打包成一个标准件,在任何装了 Docker 的机器上行为完全一致

这篇不讲容器底层原理(namespacecgroup 有机会单独写),专注一条最短实战路径:核心概念常用命令 Dockerfile → 瘦身编排避坑。

一、三个核心概念:镜像是模板,容器是实例

概念

一句话解释

类比

镜像(Image

只读模板:应用 + 依赖 + 运行环境

安装光盘

容器(Container

用镜像跑起来的运行实例

光盘装出来的系统

仓库(Registry

存放镜像、可拉取推送

应用商店

 

理解三者的关系,后面所有命令都有了坐标:docker pull 从仓库拉镜像,docker run 用镜像起容器,docker build 把你的应用做成镜像,docker push 推回仓库。

和虚拟机比,容器共享宿主机内核,不需要 Guest OS

维度

虚拟机

容器

启动速度

分钟级

秒级

体积

GB

MB

隔离强度

强(独立内核)

中(共享内核)

资源开销

 

隔离强度换轻快——对绝大多数应用交付场景,这笔交易稳赚。

二、十分钟上头:安装与第一批命令

装好 Docker DesktopWindows/Mac)或 Docker EngineLinux)后,先跑通三条命令感受一下:

docker run hello-world          # 拉镜像并运行官方示例

docker run -d -p 8080:80 --name web nginx   # 后台起一个 nginx,宿主 8080 映射容器 80

docker logs -f web              # 跟踪容器日志

打开 http://localhost:8080,看到 nginx 欢迎页,你就已经完成了"容器跑 Web 服务"的全流程——没有往宿主机装任何依赖。

高频命令速查:

命令

作用

docker ps / docker ps -a

看运行中 / 全部容器

docker images

本地镜像列表

docker stop <name> / docker rm <name>

停止 / 删除容器

docker logs -f --tail 100 <name>

看日志

docker exec -it <name> sh

进容器排查(生产慎用)

docker cp <name>:/path ./local

容器与宿主机互拷文件

docker inspect <name>

看容器全部元数据

 

三、写一个自己的镜像:Dockerfile 逐行讲

假设有一个 Node 应用要打包:

# 构建阶段:装依赖、编译产物

FROM node:20-alpine AS builder

WORKDIR /app

COPY package*.json ./

RUN npm ci

COPY . .

RUN npm run build

 

# 运行阶段:只带走运行需要的东西

FROM node:20-alpine

WORKDIR /app

ENV NODE_ENV=production

COPY --from=builder /app/dist ./dist

COPY --from=builder /app/node_modules ./node_modules

EXPOSE 3000

CMD ["node", "dist/main.js"]

逐行拆重点:

·         FROM:基础镜像,选 alpine/slim 系而不是完整版,起点就小一个量级

·         WORKDIR:容器内工作目录,后续指令都相对它

·         COPY package*.json ./ RUN npm ci故意把依赖清单和源码分开拷——Docker 的分层缓存会记住依赖层,只要 package.json 没变,改代码重新构建时不用重装依赖,构建从分钟级掉到秒级

·         COPY --from=builder:多阶段构建,编译工具链全部留在 builder 阶段,最终镜像只装"能跑"的东西

·         CMD:容器启动命令,必须是一个前台进程(第一坑,见第六节)

构建与运行:

docker build -t myapp:1.0 .

docker run -d -p 3000:3000 --name myapp myapp:1.0

再配一个 .dockerignore(作用同 .gitignore,先把垃圾挡在构建上下文外):

node_modules

.git

*.log

.env

Dockerfile

.dockerignore

四、镜像瘦身三板斧

镜像大小直接决定拉取速度和部署速度:

1.       多阶段构建:上面已经用了,通常能砍掉一半以上

2.       换小基础镜像node:20(约 1GBnode:20-slim(约 200MBnode:20-alpine(约 130MB);注意 alpine musl libc,个别原生依赖需要重新编译

3.       `.dockerignore` + 合并 RUN 指令:少把无关文件塞进上下文,少生成层

验证效果:

docker images myapp

docker history myapp:1.0   # 看每一层多大,谁胖一目了然

五、数据、网络与编排

数据别放容器里

容器是"用完即弃"的,写进容器文件系统的数据随容器删除一起消失。持久化用卷:

docker volume create pgdata

docker run -d --name pg -v pgdata:/var/lib/postgresql/data postgres:16

开发时想把代码实时挂进容器,用绑定挂载:-v $(pwd):/appWindows PowerShell 里是 -v ${PWD}:/app)。

容器之间怎么通信

同一个自定义网络里,容器可以用容器名当域名互访:

docker network create appnet

docker run -d --name redis --network appnet redis:7-alpine

docker run -d --name myapp --network appnet -e REDIS_URL=redis://redis:6379 myapp:1.0

多容器项目:docker compose

应用加缓存加数据库,手敲三条 run 太原始。compose 把整套拓扑写成一个 yaml

services:

  web:

    build: .

    ports:

      - "3000:3000"

    environment:

      - REDIS_URL=redis://redis:6379

    depends_on:

      - redis

  redis:

    image: redis:7-alpine

    volumes:

      - redis-data:/data

 

volumes:

  redis-data:

之后整套系统就是两个命令:

docker compose up -d      # 一键起全套(自动建网络)

docker compose down       # 一键收摊

两个细节:compose 里服务名(webredis)就是网络里的主机名;depends_on 只保证启动顺序,不保证服务就绪——应用里要做连接重试。

六、新手最容易踩的五个坑

1. 容器起来就退出。 容器的生命周期 = CMD 进程的生命周期。CMD 里跑一个后台启动脚本然后脚本退出,容器立刻停止。原则:CMD 必须前台运行nginx daemon off;Node 直接 node server.js)。

2. 日志把磁盘吃满。 默认 json-file 日志驱动不轮转,跑几个月能把盘写爆。生产环境要限制:

docker run --log-opt max-size=10m --log-opt max-file=3 ...

3. 时区是 UTC 日志时间差八小时。加环境变量并装 tzdataENV TZ=Asia/Shanghaialpine 需额外 apk add tzdata)。

4. 数据写在容器层。 数据库容器升级 = 数据全没。一切需要留下的数据都走 volume

5. 磁盘被镜像和悬空层塞满。 定期体检和清理:

docker system df            # 看占用

docker image prune -f       # 清悬空镜像(安全)

docker system prune -a      # 清所有未使用镜像(确认没有要留的再跑)

七、什么时候轮到 K8s

Docker 单机 + compose 能覆盖开发环境、小项目和单机部署。当你需要多机调度、自愈重启、滚动发布、弹性扩缩容——再上 Kubernetes。别跳级:没有容器化基础直接上 K8s,等于把复杂度从"环境"搬到"平台",坑一个不少还更贵。

速查卡

场景

命令

起容器

docker run -d -p 8080:80 --name web nginx

看日志

docker logs -f --tail 100 web

进容器

docker exec -it web sh

构建镜像

docker build -t myapp:1.0 .

瘦身诊断

docker history myapp:1.0

数据持久化

-v pgdata:/var/lib/postgresql/data

一键编排

docker compose up -d

磁盘体检

docker system df

 

写在最后

容器化的本质是把"环境"从玄学变成工程:环境被声明在 Dockerfile 里、被版本管理、被一键复现。第一次配好可能要一两天,之后新同事入职是五分钟 docker compose up,而不是一整天装环境。

从给一个老项目写 Dockerfile 开始吧——这是容器化路上性价比最高的第一步。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。