chore: init company-deploy-skills with dokploy-gitea-deploy

This commit is contained in:
deploy-bot
2026-07-31 09:47:16 +08:00
commit 7b56a16fbc
7 changed files with 1125 additions and 0 deletions

View File

@@ -0,0 +1,183 @@
# 技术栈构建约定Agent 改 Dockerfile 时遵循)
## 通用
1. 基础镜像Docker Hub`python:*` / `node:*` / `nginx:*`),避免默认 `ghcr.io`
2. 多阶段或「依赖层 → 代码层」拆分。
3. BuildKit`--mount=type=cache` 缓存包管理器目录。
4. 生产 `CMD`/`ENTRYPOINT` 明确;进程监听 **`spec.port`**(与 plan 一致)。
5. 健康检查:实现 `/healthz` 或约定路径,写入 `spec.healthcheckPath`
6. Dokploy **不要每次 cleanCache**
7. **有状态数据写挂载路径**(见下),不要只写容器可写层。
---
## 持久化与 `/data`MCP 默认)
控制面默认为每个应用挂载 **容器内 `/data`**(可配置,见 `inspect_project``policy.storage`)。
| 约定 | 说明 |
|------|------|
| SQLite / 本地文件 | 路径放在 `/data/...`,例如 `/data/app.db` |
| 上传目录 | 额外 `persistence``{ "name": "uploads", "mountPath": "/var/uploads" }` |
| 日志 | ephemeral 可写容器内;需保留则挂卷 |
| 多卷 | `spec.persistence[]`;若未包含 `/data`,控制面仍自动补默认卷 |
示例环境变量(应用代码侧):
```text
DATA_DIR=/data
DATABASE_PATH=/data/app.db
```
**禁止**假设宿主机路径;只认容器内 `mountPath`
---
## 托管数据库Postgres / MySQL
plan 中声明 `spec.databases[]` 后,控制面注入连接串环境变量(默认名 `DATABASE_URL`)。
应用应:
1. 启动时读取 `process.env.DATABASE_URL`(或自定义 `envVar`
2. **不要**在镜像里写死密码
3. 迁移在启动脚本或独立 job 中执行(注意并发与锁)
示例Node
```js
const url = process.env.DATABASE_URL;
if (!url) throw new Error("DATABASE_URL is required");
```
示例Python
```python
import os
url = os.environ.get("DATABASE_URL")
if not url:
raise RuntimeError("DATABASE_URL is required")
```
Docker 内网 host 由 Dokploy 管理;应用只消费完整 URL。
---
## Pythonuv 优先)
检测:`pyproject.toml` + `uv.lock`,或 `requirements.txt`
推荐结构:
```dockerfile
FROM python:3.12-slim-bookworm
WORKDIR /app
ENV UV_LINK_MODE=copy \
UV_CONCURRENT_DOWNLOADS=16 \
UV_HTTP_TIMEOUT=120 \
PYTHONUNBUFFERED=1
ARG PIP_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/
ENV UV_DEFAULT_INDEX=${PIP_INDEX_URL} \
UV_INDEX_URL=${PIP_INDEX_URL} \
PIP_INDEX_URL=${PIP_INDEX_URL}
RUN --mount=type=cache,target=/root/.cache/pip \
pip install --no-cache-dir "uv>=0.6.0"
COPY pyproject.toml uv.lock README.md ./
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev --no-install-project
COPY src ./src
# …其它源码…
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev
# 监听 0.0.0.0,端口与 plan.spec.port 一致
ENV DATA_DIR=/data
EXPOSE 8000
CMD ["uv", "run", "your-entrypoint"]
```
说明:
- 慢点通常是 **PyPI 下包**,不是 `pip install uv` 本身。
- 主机 `~/.pip/pip.conf` **不会**自动进容器;必须 Dockerfile/build-arg。
- 飞书长连接类:`replicas=1` + 状态进 `/data``exposeWeb: false` 若无需公网页。
---
## Nodepnpm / npm
检测:`package.json`,优先 `pnpm-lock.yaml``package-lock.json``yarn.lock`
推荐结构standalone / 需 `node` 运行):
```dockerfile
FROM node:22-bookworm-slim AS deps
WORKDIR /app
RUN corepack enable
COPY package.json pnpm-lock.yaml ./
# 可选COPY .npmrc ./
RUN --mount=type=cache,target=/root/.local/share/pnpm/store \
pnpm install --frozen-lockfile
FROM node:22-bookworm-slim AS build
WORKDIR /app
RUN corepack enable
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN pnpm run build
FROM node:22-bookworm-slim AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV DATA_DIR=/data
COPY --from=build /app/dist ./dist
COPY --from=build /app/package.json ./
COPY --from=deps /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/index.js"]
```
静态前端Vite 等)可用 `nginx:stable-alpine``dist``spec.port` 多为 `80`
Registry 加速示例 `.npmrc`(可提交或构建时注入):
```ini
registry=https://registry.npmmirror.com
```
---
## Docker Compose
- 当前 MCP MVP **仅** `buildType: dockerfile` 单应用。
- 多服务 Composelegacy / 运维在 Dokploy 选 Compose 类型,或拆成多个 MCP 应用 + 托管 DB。
- 生产注意DB 密码走 `databases[]` 注入;卷走 `persistence[]`
---
## 构建耗时预期(经验)
| 场景 | 预期 |
|------|------|
| 首次全量(弱网 + 下包) | 1040 分钟可能 |
| 依赖层已缓存,只改代码 | 数分钟内 |
| 仅拉预构建业务镜像 | 通常更短 |
若日志出现 `Prepared N packages in 30m`:换源 + 分层缓存 + 禁止 cleanCache长期用私有镜像仓库。
---
## 与 plan.spec 对齐检查
部署前 Agent 自检:
- [ ] 容器监听 `0.0.0.0:$PORT`,且 `spec.port` 一致
- [ ] 有状态路径落在 `/data` 或其它 `persistence.mountPath`
- [ ] 需要 PG/MySQL 时 plan 带 `databases`,代码读对应 env
- [ ] Web 服务 `exposeWeb: true`默认Worker 显式 `false`
- [ ] `.gitignore` 排除 `.env`、密钥、本地 db