Files
company-deploy-skills/dokploy-gitea-deploy/references/stack-profiles.md

7.3 KiB
Raw Blame History

技术栈构建约定Agent 改 Dockerfile 时遵循)

通用

  1. 基础镜像Docker Hubpython:* / node:* / nginx:*),避免默认 ghcr.io
  2. 多阶段或「依赖层 → 代码层」拆分。
  3. BuildKit--mount=type=cache 缓存包管理器目录。
  4. 生产 CMD/ENTRYPOINT 明确;进程监听 spec.port(与 plan 一致)。
  5. 健康检查:实现 /healthz 或约定路径,写入 spec.healthcheckPath
  6. Dokploy 不要每次 cleanCache
  7. 有状态数据写挂载路径(见下),不要只写容器可写层。

持久化与 /dataMCP 默认)

控制面默认为每个应用挂载 容器内 /data(可配置,见 inspect_projectpolicy.storage)。

约定 说明
SQLite / 本地文件 路径放在 /data/...,例如 /data/app.db
上传目录 额外 persistence{ "name": "uploads", "mountPath": "/var/uploads" }
日志 ephemeral 可写容器内;需保留则挂卷
多卷 spec.persistence[];若未包含 /data,控制面仍自动补默认卷

示例环境变量(应用代码侧):

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

const url = process.env.DATABASE_URL;
if (!url) throw new Error("DATABASE_URL is required");

示例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

推荐结构:

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 + 状态进 /dataexposeWeb: false 若无需公网页。

Nodepnpm / npm

检测:package.json,优先 pnpm-lock.yamlpackage-lock.jsonyarn.lock

Dockerfile 硬规则踩过的坑Agent 必守)

错误 现象 正确做法
build 阶段 npm ci 之前 ENV NODE_ENV=production nest: not found / vite: not found;日志里 packages 只有几百个(缺 devDependencies npm ci(装全量含 dev ENV NODE_ENV=productionnpm run build
不设 Node 堆、大前端 Vite 打包 FATAL ERROR: JavaScript heap out of memory build 阶段:ENV NODE_OPTIONS=--max-old-space-size=3072(小机 34G 可试 2560
multi-stage 里 build 与 runtime 无依赖 Docker 并行 两个 npm ci,小机内存翻倍易 OOM runtime 至少 COPY --from=build … 一件产物,让 build 先完成
用用户 SSH 推 Gitea Permission denied ensure_repositorypushUrl,见 SKILL

推荐Nest + Vite 全栈模板

FROM node:22-bookworm-slim AS build
WORKDIR /app
# ① 提高堆;② 此时不要 NODE_ENV=production
ENV NODE_OPTIONS=--max-old-space-size=3072

COPY package.json package-lock.json ./
RUN npm ci --ignore-scripts

COPY . ./
# ③ 仅编译时 production
ENV NODE_ENV=production
RUN npm run build:prod && npm cache clean --force

FROM node:22-bookworm-slim AS runtime
WORKDIR /app
ENV NODE_ENV=production \
    SERVER_HOST=0.0.0.0 \
    SERVER_PORT=3000 \
    DATA_DIR=/data

COPY package.json package-lock.json ./
# ④ 依赖 build避免与 vite 并行 npm ci
COPY --from=build /app/package.json /tmp/.build-done
RUN npm ci --omit=dev --ignore-scripts && npm cache clean --force
COPY --from=build /app/dist ./

EXPOSE 3000
CMD ["node", "server/main.js"]

推荐:较轻的 Node APIpnpm

FROM node:22-bookworm-slim AS build
WORKDIR /app
ENV NODE_OPTIONS=--max-old-space-size=2048
RUN corepack enable
COPY package.json pnpm-lock.yaml ./
RUN --mount=type=cache,target=/root/.local/share/pnpm/store \
    pnpm install --frozen-lockfile
COPY . .
ENV NODE_ENV=production
RUN pnpm run build

FROM node:22-bookworm-slim AS runner
WORKDIR /app
ENV NODE_ENV=production DATA_DIR=/data
COPY --from=build /app/dist ./dist
COPY --from=build /app/package.json ./
COPY --from=build /app/node_modules ./node_modules
# 若 node_modules 含 dev可改为 runner 单独 pnpm install --prod
EXPOSE 3000
CMD ["node", "dist/index.js"]

静态前端Vite 等)可用 nginx:stable-alpinedistspec.port 多为 80
纯静态站构建同样需要 devDependenciesvite在 build 阶段装全。

Registry 加速示例 .npmrc

registry=https://registry.npmmirror.com

部署前 Agent 自检Node

  • Dockerfile 没有在安装依赖前设置 NODE_ENV=production
  • nest / vite / tsc 等 CLI 在 devDependencies 且 build 阶段能装到
  • 大前端:NODE_OPTIONS=--max-old-space-size=3072(或更高,视机器)
  • multi-stageruntime 依赖 build避免并行双 npm ci
  • 运行 CMD 只跑编译产物,在 runtime 再 nest build

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