这篇先准备本地开发环境,再把带版本号的 API 镜像推送到 Docker Hub。开发和构建都在 Mac 与 OrbStack 上完成,Ubuntu VPS 负责通过 Docker Compose 运行镜像。VPS 只保存部署文件、环境变量、Nginx 配置和数据卷,不需要上传 Git 仓库或 src 目录。
注意:多阶段构建不能绝对保护源码。最终镜像里可以不包含 TypeScript 文件,但编译后的 JavaScript 仍能被分析。密码、令牌和私钥不要写进镜像。
一、部署方式与准备条件
本地需要安装 OrbStack、Node.js LTS、npm 和 Git,并准备一个 Docker Hub 账号。下文在 macOS 上操作,PostgreSQL 跑在 OrbStack 容器里。
VPS 可以从下面的配置起步:
- 系统:Ubuntu 24.04 LTS(或仍受支持的 LTS)
- 配置:2 vCPU、4 GB RAM、40 GB 以上 SSD/NVMe
- 网络:公网 IPv4,开放 TCP 80/443
- 安全:SSH 仅对可信 IP 开放
1 GB 内存也能用于试验,不过 API、PostgreSQL 和 Docker 跑在一起时,余量会很小。
二、准备本地数据库
本地 API 需要一个 PostgreSQL 实例。这里用 OrbStack 容器运行数据库,并把端口限制在本机。
创建 compose.dev.yml:
1 | services: |
启动并验证:
1 | docker compose -f compose.dev.yml up -d |
本机运行 API 时的数据库连接字符串:
1 | DATABASE_URL=postgresql://app_user:***@localhost:5432/app_db |
端口绑定到 127.0.0.1 后,数据库只接受来自本机的连接。
三、构建并验证生产镜像
下面的 Dockerfile 假设 npm run build 会输出 dist,应用入口是 dist/server.js:
1 | FROM node:22-alpine AS build |
用 .dockerignore 排除依赖目录、环境变量文件等构建上下文内容:
1 | node_modules |
先在本地构建镜像并启动容器,确认服务可以运行:
1 | docker build -t YOUR_DOCKERHUB_USER/backend-api:1.0.0 . |
如果项目使用 Prisma 或原生模块,构建镜像时可能还要补充生成或编译步骤,具体取决于项目依赖。
四、选择镜像仓库
镜像仓库地址由仓库域名、用户名、镜像名和标签组成。Docker Hub 的地址格式是 docker.io/<用户名>/<镜像名>:<标签>,例如 docker.io/alice/backend-api:1.0.0。业务 API 一般放在私有仓库中。
各容器仓库选型对比:
| 仓库 | 适用场景 |
|---|---|
| Docker Hub | 配置简单、使用广泛;业务镜像建议设为私有 |
| GHCR | 项目和 CI 都在 GitHub 时比较顺手 |
| GitLab Container Registry | 项目使用 GitLab CI 时省去额外集成 |
| 云厂商仓库 | 服务长期部署在同一家云厂商时可优先考虑 |
私有仓库和拉取额度会变化,以各平台官网当前政策为准。
五、发布镜像
选好仓库后,在 Docker Hub 创建名为 backend-api 的私有仓库,再用 Personal Access Token 登录并推送带版本号的镜像:
1 | docker login |
需要时,也可以给同一个镜像附加 latest 标签:
1 | docker tag YOUR_DOCKERHUB_USER/backend-api:1.0.0 YOUR_DOCKERHUB_USER/backend-api:latest |
推送前确认 API 已连接本地 PostgreSQL,关键测试已经通过,并提供了 GET /health 健康检查端点。还要确认镜像里没有密码或令牌,并为本次发布使用新的版本标签。
生产 Compose 应固定使用 1.0.0 之类的明确版本,便于回滚。
总结
至此,本地环境和 PostgreSQL 已准备好,生产镜像也已推送到 Docker Hub。下一篇会在 Ubuntu VPS 上拉取这个镜像,配置 Nginx,并申请和自动续期 HTTPS 证书。