浏览 AI使用教程

Docker 项目部署教程:先说明端口、卷、环境变量和健康检查

容器显示 Up,只说明进程还在。端口、卷、环境变量、依赖和健康检查要一起验证,才能确认服务可访问、数据也不会随重建消失。

按实际操作顺序推进

每完成一段就检查当前输出,确认结果符合预期后再继续。

  1. 01准备三份文件使用同一3000/8080约定
  2. 02执行先检查解析,再启动和重建
  3. 03检查为什么“健康检查通过,功能接口仍失败”还不能交付
  4. 04完成容器运行契约通过哪些检查才算完成
从手头这一份材料开始

Docker 容器已经 Up,浏览器为什么还是打不开

教学服务在容器内监听3000,宿主仅通过127.0.0.1:8080访问;写入/app/data/note.txt后重建容器,再确认命名卷中的文件仍可读。

本例专门解释端口、持久卷与就绪检查。真实数据库依赖、账号和外部代理需要另行接入验证,不能从此例推定生产可用。

  • 端口与监听地址一致
  • 持久卷经重建验证
  • 健康、日志和停止行为正常
本例材料

动手前,把材料和不能改的部分定下来

需要确认本例内容
现有材料已安装Docker Engine/Desktop及Compose插件;下方给出server.mjs、Dockerfile、compose.yaml三个完整文件;本练习没有数据库和真实密钥。
不能越过的边界端口只绑定宿主回环地址;不使用生产数据。停止服务用docker compose down,练习数据由命名卷保留;不要附加-v删除卷。
要交付的结果容器运行契约
实际操作

Docker 项目部署教程,从“镜像与命令”开始做

镜像与命令

写基础镜像、目标架构、构建上下文、启动命令和非 root 用户要求。

端口与网络

区分容器监听端口、宿主映射、服务名和外部入口,说明是否经过代理。

卷与数据

标持久化目录、只读挂载、初始化和备份;明确删除容器是否应保留数据。

变量与密钥

列名称、来源、必填、默认和重启影响,不把生产值放进 Compose 或镜像层。

健康与依赖

健康检查使用真实就绪条件,依赖服务有超时和重试;启动顺序不替代可用性判断。

完整最小服务

三份文件使用同一3000/8080约定

server.mjs

本机练习服务

import http from 'node:http';
import { access, readFile, writeFile } from 'node:fs/promises';
import { constants } from 'node:fs';
const file = '/app/data/note.txt';
const server = http.createServer(async (req, res) => {
  try {
    if (req.url === '/healthz') { await access('/app/data', constants.W_OK); res.end('ready'); return; }
    if (req.url === '/note' && req.method === 'POST') {
      let body = ''; for await (const part of req) body += part;
      await writeFile(file, body); res.end('saved'); return;
    }
    if (req.url === '/note' && req.method === 'GET') { res.end(await readFile(file)); return; }
    res.writeHead(404); res.end('not found');
  } catch (error) { res.writeHead(error.code === 'ENOENT' ? 404 : 503); res.end(error.code || 'unavailable'); }
});
server.listen(3000, '0.0.0.0');
process.on('SIGTERM', () => server.close(() => process.exit(0)));
Dockerfile

镜像目录与用户

FROM node:22-alpine
WORKDIR /app
RUN mkdir -p /app/data && chown node:node /app/data
COPY --chown=node:node server.mjs /app/server.mjs
USER node
EXPOSE 3000
CMD ["node", "server.mjs"]
compose.yaml

宿主8080映射容器3000

services:
  app:
    build: .
    ports:
      - "127.0.0.1:8080:3000"
    volumes:
      - lesson-data:/app/data
    healthcheck:
      test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3000/healthz').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
      interval: 10s
      timeout: 3s
      retries: 3
volumes:
  lesson-data:

healthz检查本例数据目录可写,不等于每个业务端点通过;镜像标签是本例选用版本,生产需自行固定经过验证的镜像摘要。

验证顺序

先检查解析,再启动和重建

PowerShell

在三份文件所在目录执行

docker compose config
# 确認只有本例端口和命名卷后启动
docker compose up -d --build
docker compose ps
Invoke-WebRequest 'http://127.0.0.1:8080/healthz'
Invoke-WebRequest 'http://127.0.0.1:8080/note' -Method Post -Body 'lesson-persist-1'
(Invoke-WebRequest 'http://127.0.0.1:8080/note').Content
docker compose up -d --force-recreate
# 等到health为healthy后再次读取,预期仍为lesson-persist-1
(Invoke-WebRequest 'http://127.0.0.1:8080/note').Content
docker compose logs --tail 50 app
# 停止练习并保留卷:
docker compose down

端口占用时改宿主左侧8080并同步请求地址,容器右侧3000和server监听保持一致;503先看数据目录权限,重建后404则检查挂载是否仍为同一命名卷。

预期结果

完成后的容器运行契约

预期GET /healthz返回200;POST /note写入后GET /note能读回;docker compose up -d --force-recreate后内容保持一致。需以当前机器的请求、inspect和日志验证;本页不声称已在你的Docker环境实测。

常见失败

为什么“健康检查通过,功能接口仍失败”还不能交付

健康检查通过,功能接口仍失败

原因
健康只返回固定 200,没有检查关键依赖
怎么改
区分存活与就绪检查,关键流程另做外部冒烟测试
验收方式

容器运行契约通过哪些检查才算完成

依据与范围

本页实际使用的资料