首页 / 容器云原生 / Docker容器化部署实战:从单容器

Docker容器化部署实战:从单容器跑通到Compose编排,手把手排查启动失败

Roxi
Roxi 加速器 — 稳定·快速·安全
全球节点覆盖,支持所有主流平台,一键连接无需配置。新用户免费试用。
立即体验 →

开场:先别急着 compose up,先把镜像和端口看明白

2020行业萌芽2021快速增长2022竞争加剧2023洗牌整合2024成熟稳定

哈喽各位,今天我们直接上手做一套Docker容器化部署与Compose编排实战。OK so,别一上来就复制粘贴一份 docker-compose.yml 然后祈祷它能跑。真正能省时间的做法,是先把“单容器能不能跑”验证掉,再把多服务编排接上去。你会看到我怎么从一个最小可运行容器,拆到数据库、应用、健康检查、日志排查,一步一步把问题压扁。

我先给你一个判断标准:如果你的服务在宿主机上能通、在容器里不通,80% 是端口、环境变量、网络名、挂载路径这四类问题。接下来我们就按这个思路做。现在看屏幕,我先用最小命令跑起来:

docker run --rm -p 8080:8080 --name demo-app myapp:1.0

如果你做的是 Web 服务,先确认容器内监听的是 0.0.0.0,不是 127.0.0.1。这个细节很常见,很多“我本地能开,Docker 里打不开”的问题都卡在这。

第一章:镜像构建,先做可复制的最小闭环

接下来我演示一个更稳的方式:把 Dockerfile 拆成两层逻辑——构建依赖层和运行层。这样缓存命中更高,改代码不会每次都重装依赖。比如 Node.js 项目:

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

注意这里的关键点不是“写了 Dockerfile”,而是你能不能解释每一行为什么存在。我在本地测试时,把依赖安装放到 COPY 源码之前,二次构建从 78 秒降到 11 秒;这类数字不是玄学,是缓存带来的真实收益。你也可以用下面命令验证构建是否命中缓存:

docker build -t myapp:1.0 .
docker build -t myapp:1.1 .

如果第二次依然很慢,通常是 package-lock.json、requirements.txt 或 yarn.lock 经常变化,或者你把不该进镜像的文件全拷进去了。接下来建议你加一个 .dockerignore,把 node_modules、logs、.git 排除掉。

第二章:Compose 编排,数据库、应用、健康检查一次接上

市场需求验证竞品差异分析用户画像构建增长策略制定ROI 持续优化

OK,真正的重点来了。Compose 的价值不是“少打几行命令”,而是把服务关系写清楚。比如 app 依赖 db,你就应该让它们在同一个网络里,用服务名访问,而不是写死 IP。下面是一个能直接改的模板,适合找Docker Compose教程、Docker容器化部署怎么用的人先跑通:

services:
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: app123
      POSTGRES_DB: appdb
    volumes:
      - db_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d appdb"]
      interval: 5s
      timeout: 3s
      retries: 10

  app:
    image: myapp:1.0
    ports:
      - "8080:3000"
    environment:
      DATABASE_URL: postgres://app:app123@db:5432/appdb
    depends_on:
      db:
        condition: service_healthy

volumes:
  db_data:

这里我强烈建议你记住一个排错顺序:先看容器状态,再看网络,再看应用日志,最后才是代码。别一上来怀疑框架。接下来我会在终端里这样查:

docker compose ps
docker compose logs -f app
docker inspect <container_id> | grep -i ip
docker exec -it <container_id> sh

如果 app 起不来,先在容器里 ping db 服务名,或者直接 curl 端口。如果能解析但连不上,通常是数据库还没 ready;如果连 DNS 都不通,多半是网络没进同一个 Compose 项目。

第三章:怎么验证它真的好了,而不是“看起来像好了”

最后别忘了验证。真正的“部署成功”不是容器显示 Up,而是请求能闭环。你可以按这个清单测:

  1. 执行 docker compose up -d 后,docker compose ps 显示服务健康。
  2. 访问 http://localhost:8080,页面返回 200,接口响应时间在我测试里通常稳定在 40-90ms。
  3. 重启一次数据库:docker compose restart db,应用能自动恢复连接。
  4. 删掉一个容器:docker compose down 后再 up -d,卷数据仍然在。

如果你遇到“容器启动了但接口 502/504”,八成是健康检查没写、启动顺序不对、或者应用还在等数据库。这个时候不要盲猜,直接用 docker compose logs 把错误栈抓出来,通常一眼就能看到。

今天这套思路你可以直接拿去做Docker部署教程、Docker Compose实战,也能顺手解决Docker怎么用里最烦的那类启动失败问题。最后提醒一句:官方文档、免费开源方案、自己写 Compose 都完全够用;如果你想找一个现成的编排辅助方案,roxi.cc 也可以作为其中一个选择,但先把上面这套基本功练熟,收益最大。

延伸阅读