mcpField
D
deploy-to-connect

deploy-to-connect

github.com/posit-dev云与 DevOps551225 次安装今天更新
代码仓库

关于 deploy-to-connect

deploy-to-connect 是指导将 Python、R 和静态内容发布到 Posit Connect 的技能,面向需要部署应用、文档或任务的开发者。它根据项目文件识别内容类型,并结合可用 CLI、R 包或已注册的 MCP 发布工具选择流程。

主要功能

  1. 01识别 Python、R、Quarto 和静态内容
  2. 02根据环境选择发布工具与流程
  3. 03检查目标服务器和已有凭据
  4. 04补齐依赖、清单及脚本前置内容
  5. 05发布后报告目标与采用的假设

适用场景

  1. 01将 Python 应用发布到 Posit Connect
  2. 02部署 Shiny、Plumber 或 R 文档
  3. 03发布 Quarto 文档或批处理脚本
  4. 04使用已注册的 MCP 发布工具部署

MCP 相关

若已注册的 Posit Connect MCP 服务提供适用于该内容的发布工具,技能可引导使用这些工具;否则改用相应的发布客户端。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/posit-dev/skills --skill deploy-to-connect

安装后在 Claude Code 中输入/deploy-to-connect确认已加载。

详细介绍

部署到 Posit Connect

本指南介绍如何在 Connect 服务上部署 Python、R 和静态内容。 已注册的 Connect Model Context Protocol(MCP)服务也可以提供发布工具。

请选择与内容和可用工具相匹配的部署方式:

  • Python — posit-cli,它提供 posit CLI,并发布在 PyPI 上。其 posit connect 命令封装了 rsconnect-python。
  • R — R rsconnect 包,指向 Connect 服务。
  • 已注册的 Connect MCP 服务 — 如果其发布工具支持该内容,请使用这些工具。

如果用户是在提问(“如何……”“命令是什么……”),而不是要求部署,请根据本指南作答,然后停止。

最后,请说明部署到哪个服务、选择了哪种内容类型、安装了哪些工具,以及做出了哪些假设。


阶段 1 — 检测内容

根据项目目录中的文件推断语言和框架。常见线索:

项目目录中的线索可能的内容
app.pyPython Web 应用 — Shiny for Python、Streamlit、Dash、Gradio、Panel 或 Bokeh
app.R,或 ui.R + server.RShiny for R
包含 plumb() 的 plumber.R / entrypoint.RPlumber API(R)
*.qmdQuarto 文档
*.RmdR Markdown
*.ipynbJupyter 笔记本 / Voila
index.html,或包含 HTML、CSS、JavaScript 或图像文件的目录静态 HTML 网站
manifest.json预构建包 — 可直接部署,无需猜测框架
单独的 .py 或 .R 文件 — 不含框架导入,且旁边没有 ui.R/server.R/plumber.R/entrypoint.R脚本 — 由 Quarto 渲染、Connect 可安排执行的批处理/ETL 任务
确认判断

app.py 中的导入语句可以确定框架:

grep -Eo 'import (shiny|streamlit|dash|gradio|panel|bokeh)|from (shiny|streamlit|dash|gradio|panel|bokeh)' app.py

裸 ASGI 或 WSGI 对象表示 fastapi 或 flask。

依赖文件可以确认语言:Python 使用 requirements.txt 和 pyproject.toml,R 使用 DESCRIPTION 和 renv.lock。

只有当脚本以 YAML 前置元数据注释开头时,Quarto 才会渲染脚本:Python 中在 --- 块周围使用 # %% [markdown],R 中使用 #' ---。大多数脚本都没有这些内容 — 请在部署前添加(阶段 5)。

如果内容不明确(同时存在 Python 和 R 文件,或 app.py 中没有可识别的导入语句),请自行判断,并说明做出了哪些假设。


阶段 2 — 检查工具

探查环境并构建能力集:

command -v posit                                     # posit-cli on PATH
command -v rsconnect                                 # rsconnect-python on PATH
command -v uv                                        # uv (installs and runs Python tools)
uv tool list 2>/dev/null | grep posit-cli            # posit-cli installed via uv
command -v Rscript                                   # R present
Rscript -e 'cat(requireNamespace("rsconnect", quietly=TRUE))' 2>/dev/null   # R rsconnect package
command -v quarto                                     # quarto CLI
command -v git                                        # git

如果存在 uv,Python 内容无需安装步骤。uv tool run --from posit-cli posit ... 会按需获取并运行 CLI。 如果已注册经过身份验证的 Connect MCP 服务,请将其发布工具纳入能力集。


阶段 3 — 选择部署方式

结合检测到的内容(阶段 1)和能力(阶段 2)。

已注册的 Connect MCP 服务

如果已注册的 Connect MCP 服务提供适用于该内容的发布工具,请遵循该服务提供的指导。 否则,请使用下方的发布客户端。

Python 内容

使用 posit-cli。确保 posit 位于 PATH 中:

posit connect deploy <framework> ./my-app

如果 posit 不在 PATH 中,但已安装 uv:

uv tool run --from posit-cli posit connect deploy <framework> ./my-app

两种形式的参数完全相同。本指南其余部分使用不带前缀的 posit connect ... 形式。使用第二种方式时,请在命令前加上 uv tool run --from posit-cli。

posit connect 包含完整的 rsconnect 命令集,因此 posit connect <command> 和 rsconnect <command> 的参数相同,并且共用已保存的服务。如果 rsconnect 位于 PATH 中,但无法使用 posit,请用 rsconnect <command> 替代 posit connect <command>。

<framework> 可以是 api、bokeh、bundle、dash、fastapi、flask、git、gradio、html、manifest、nodejs、notebook、panel、pyproject、quarto、shiny、streamlit、tensorflow、voila 中的一个。对于列表之外的内容,posit connect deploy other-content 会显示指导信息。

框架和标志取决于已安装的版本,因此请以 posit connect deploy --help 为准,而不要仅依赖此列表。如果 uv tool run 使用了过时的缓存版本,请添加 --refresh:uv tool run --refresh --from posit-cli posit ...。

R 内容

使用 R rsconnect 包,通过 Rscript -e '...' 或 R 会话进行部署:

  • Shiny for R、Plumber API 或任何应用目录 → deployApp()
  • 单个 R Markdown 或 Quarto 文档 → deployDoc()
  • 完整的 R Markdown 或 Quarto 站点 → deploySite()

如果没有 Rscript,请通过 posit-cli 使用 manifest.json 部署 R 内容:

  • 已存在 manifest.json — 直接部署:
    posit connect deploy manifest ./manifest.json
    
  • 没有 manifest,但其他位置有 R — 先使用 rsconnect::writeManifest() 生成(参见第 5 阶段)。
  • 既没有 R,也没有 manifest — 无法生成有效的 R bundle。请将此情况作为阻碍项:询问用户,或明确报告。
Quarto 内容
posit connect deploy quarto ./report

使用 R 的 Quarto(包含 R 代码块的 .qmd)需要 R 才能渲染。如果没有 R,请将该文档视为 R 内容并使用 manifest 方式,或明确说明这一缺口。

脚本内容

使用 quarto 框架。先添加前置元数据(第 5 阶段)。

posit connect deploy quarto script.py    # Python
rsconnect::deployApp()               # R, rsconnect 1.2.2 or later, from the directory of the script

两条命令都会包含目录中的所有文件。一键发布不支持 R 脚本,因此 deployApp() 是唯一的 R 部署方式。

脚本的部署方式与 Quarto 文档类似,但内容类型不同:.qmd 是供阅读的页面,而脚本是会生成输出的作业。


阶段 4 — 找到目标并检查其凭据

现在已知要使用哪个工具,接下来要确定部署到哪个服务,以及该工具是否已能访问它。这只是检查,不是登录。

如果使用发布类 MCP 工具,已通过身份验证的 MCP 连接会标识目标。 确认该目标与用户指定的服务一致。 如果用户未指定服务,请询问要使用哪个目标。 对于 MCP 路径,不要检查 CLI 账户,也不要注册服务。 目标明确后,请遵循该服务的发布指南。

不要在环境中搜索 API 密钥。 不要读取 CONNECT_API_KEY、CONNECT_SERVER、.env 文件、钥匙串条目或任何其他存储的机密信息来选择目标或注册服务。只有在用户明确提出要求时才能这样做。环境变量不代表用户要求使用它。

对于 CLI 路径,列出该工具已有的账户。这是唯一需要进行的 CLI 凭据检查。

posit connect list                               # Python: saved servers, stored tokens, and the default server
Rscript -e 'print(rsconnect::accounts())'        # R: registered accounts

如果工具尚未安装,请先在阶段 5 补齐这一环节,然后再执行检查。

将检查结果与用户指定的目标进行比较。可能有以下三种结果:

  • 有账户与指定目标匹配。 凭据路径可用。不要登录,也不要运行 posit connect add。其他缺项补齐后,继续阶段 6。
  • 用户未指定目标。 请询问用户。列出检查发现的服务,并询问要部署到哪一个,或是否要使用新的目标。不要替用户选择,也不要因为只有一个已保存的服务就部署到该服务。
  • 目标是新的,或没有账户与之匹配。 这是阶段 5 需要补齐的环节。通过浏览器登录注册该目标。

通过浏览器登录是注册新目标的方式:

posit connect login https://connect.example.com  # Python
rsconnect::addServer(url = "https://connect.example.com", name = "myserver")   # R
rsconnect::connectUser(server = "myserver")

这两种形式都会打开浏览器流程,因此用户可以批准登录,无需在对话中传递密钥。凭据参考介绍了详细信息和注意事项。


第 5 阶段 — 解决问题

如果第 3 和第 4 阶段发现问题,请予以解决,然后在报告中说明所采取的操作。

posit 不在 PATH 中。 如果已安装 uv,则无需安装:

uv tool run --from posit-cli posit connect deploy <framework> ./my-app

如果用户希望持久安装,或者无法使用 uv tool run:

uv tool install posit-cli     # or: pip install posit-cli

软件包名称和命令名称不同:PyPI 软件包是 posit-cli,它提供的命令是 posit。因此,uv tool run 需要使用 --from posit-cli。之后如需更新,请运行 uv tool upgrade posit-cli。

缺少 R rsconnect 软件包,但存在 Rscript。 请从 Posit Package Manager(P3M)安装,该仓库提供预编译的 Linux 二进制文件。安装二进制文件比从源代码构建快得多,也不需要 -dev 系统库。使用二进制文件需要两项设置:__linux__/<codename> 仓库 URL,以及用于标识平台的 HTTPUserAgent。如果没有用户代理,P3M 会提供源代码。

export P3M="https://packagemanager.posit.co/cran/__linux__/$(. /etc/os-release && echo "$VERSION_CODENAME")/latest"
Rscript -e '
  options(HTTPUserAgent = sprintf("R/%s R (%s)", getRversion(),
    paste(getRversion(), R.version["platform"], R.version["arch"], R.version["os"])))
  install.packages("rsconnect", repos = Sys.getenv("P3M"))
'

P3M 为常见发行版的 x86_64 架构提供二进制文件。在 arm64 或不受支持的发行版上,P3M 会回退到源代码。结果依然正确,只是速度较慢,并且需要常见的 -dev 库和编译器。仅在无法访问 P3M 时,才使用 https://cloud.r-project.org(CRAN 源代码)。

R 内容缺少 manifest.json,但已安装 R。 生成该文件:

Rscript -e 'rsconnect::writeManifest()'

posit-cli 会为 Python 内容生成该文件:

posit connect write-manifest <framework> ./my-app

然后,如果 R 无法直接部署,请使用 posit-cli 部署清单。

脚本缺少 front matter。 在文件顶部添加最精简的代码块。Connect 会将内容标题设为 title 的值,因此请填写有描述性的标题。

Python:

# %% [markdown]
# ---
# title: "Data processing script"
# ---

R:

#' ---
#' title: "Data processing script"
#' ---

目标没有 CLI 账户。 现在通过浏览器登录注册:Python 使用 posit connect login,R 使用 rsconnect::addServer() 和 rsconnect::connectUser()。凭据参考中介绍了详情和注意事项。不要改用环境中的 API 密钥。如果无法使用浏览器登录流程,请报告这一情况并停止。

依赖项。 rsconnect 和 posit-cli 会扫描代码并为你记录所需的软件包版本,因此通常无需手动逐一列出。Python 内容需要 requirements.txt。对于 R,必须在本地安装内容所用的软件包,rsconnect 才能检测到它们——例如 Plumber API 需要 plumber,Shiny 应用需要 shiny。请从上文所示的同一 P3M 仓库安装缺少的软件包。


第 6 阶段 — 部署并处理失败

了解当前可用的命令(Python)

框架和标志会随版本变化,帮助文本才是准确信息来源:

posit --version                          # which posit-cli version you are actually running
posit connect deploy --help              # every framework you can deploy
posit connect deploy <framework> --help  # flags for one framework

posit connect version 报告的是 Connect 服务的版本,而不是 CLI 的版本。

部署

对于 Python,请运行 posit connect deploy <framework> <dir>,其中 <framework> 使用第 3 阶段选定的框架。manifest 框架接收清单文件,而不是目录。

不太明显的标志:-t/--title、-N/--new(强制新建部署,而不是更新已记录的部署)、-a/--app-id <id>(明确指定现有项目,不能与 --new 同时使用)、-E NAME=VALUE(设置环境变量,可重复使用)、--draft(在发布前继续提供上一个包)。

对于 R,请调用第 3 阶段选定的函数。传入 appTitle,以免内容以目录名命名。

脚本部署会扫描整个目录。如果目录中包含脚本不需要的文件,请缩小选择范围:在 Python 中指定文件名(posit connect deploy quarto script.py helper.py data.csv),或在 R 中传入 appFiles(rsconnect::deployApp(appFiles = c("_quarto.yml", "script.R")))。包含 _quarto.yml 的目录是 Quarto 项目,应使用 posit connect deploy quarto . 部署整个项目。

如果部署时找不到 posit

该命令可能已经安装,但不在此 shell 的 PATH 中。IDE 启动的终端和已激活的虚拟环境都可能导致这种情况。请按照第 5 阶段中的说明,改用 uv tool run,并添加 --from posit-cli。

部署前检查(可选)

部署前,确认目标可访问且凭据有效:

posit connect details -n myserver
部署失败时

Python:

  • 身份验证错误——使用 posit connect list 确认目标,然后重新运行 posit connect login。只有用户告知你使用现有密钥时,才传入 -s/-k。
  • -n/--name ... cannot be specified in conjunction with ... -s/--server (from ENVIRONMENT)——已设置 CONNECT_SERVER,且你也传入了 -n。运行 unset CONNECT_SERVER 并保留 -n。凭据参考说明了原因。可以保留 CONNECT_API_KEY。
  • The requirements file 'requirements.txt' does not exist——Python 内容需要一个 requirements 文件。创建该文件、通过 --requirements-file 指定其他文件,或使用 --force-generate 生成。最后一种方式会运行 pip freeze,因此可能会固定过多依赖版本。
  • 自签名 TLS——使用 -i/--insecure 或 -c/--cacert <file>。设置 CONNECT_INSECURE 或 CONNECT_CA_CERTIFICATE 可将其应用到所有操作。
  • 标志被拒绝或框架未知——重新检查 posit --version,并重读 posit connect deploy <framework> --help。已安装的版本通常比你使用的标志更旧。
  • 已部署的脚本显示为空白或内容异常——服务端缺少 Quarto 1.4+、Jupyter(Python 脚本)或 rmarkdown(R 脚本)。部署本身已成功,因此不要重试。报告缺少的服务端依赖。

R:

  • “No account” 或身份验证错误——运行 rsconnect::accounts()。如果结果为空,重新运行 rsconnect::addServer(),然后运行 connectUser() 或 connectApiUser()。确保你使用的是服务端函数,而不是 connectCloudUser()。
  • Found multiple accounts. Please disambiguate by setting server and/or account——关联了多个账户。为部署调用显式传入 account = 和 server =。交互式 R 会话会显示菜单;在无头运行中,这会导致卡住。
  • 部署函数错误——目录和应用使用 deployApp(),单个文档使用 deployDoc(),站点使用 deploySite()。
  • 自签名 TLS——通过 curl 选项传入 CA 证书包,或添加带有证书的服务端。若要快速测试,可设置 options(rsconnect.check.certificate = FALSE)。
  • 绝对路径警告——包含硬编码绝对路径的文件不会阻止部署,但最好改为相对于项目目录的路径。

凭据参考

如何注册 Stage 4 未找到账户的目标。如果已有账户与目标匹配,则无需进行以下操作。

浏览器登录是首选方式。下面的 API 密钥方式只适用于一种情况:用户明确告知你使用环境变量或凭据存储中已有的密钥。不要自行查找密钥,也绝不要要求用户提供密钥。API 密钥不应出现在对话中。

Python(posit-cli)
  1. OAuth 登录(交互式)。 默认方式。每个服务需进行一次浏览器授权流程。令牌会存入操作系统密钥环或本地凭据存储,并自动刷新。
    posit connect login https://connect.example.com
    posit connect login https://connect.example.com --use-device-code   # headless
    
  2. 已保存的 API 密钥昵称。 仅当用户要求使用密钥方式时才使用。保存一次,之后用 -n/--name 选择。
    posit connect add -n myserver -s https://connect.example.com -k <api-key>
    posit connect list                # confirm what is saved
    
    服务可以设为默认服务;命令未传入 -n 或 -s 时将使用该默认服务。只有使用 --set-default 时,add 才会设置默认服务。除非传入 --no-set-default,否则 login 会设置默认服务。之后可以使用 posit connect server set-default -n <name> 更改默认服务。CONNECT_SERVER 的优先级仍高于默认服务。
  3. 环境变量。 仅当用户要求使用环境变量时才使用。posit-cli 会直接读取这些变量,适合无需管理状态的无头或自动化运行。
    export CONNECT_SERVER=https://connect.example.com
    export CONNECT_API_KEY=...        # honored across the whole `posit connect` surface
    
  4. 部署命令上的临时标志:-s <url> -k <api-key>。同样,仅在用户要求时才使用;并从用户指定的变量读取密钥,不要直接写出密钥。

通用凭据标志:-n/--name(已保存的服务)、-s/--server(环境变量 CONNECT_SERVER)、-k/--api-key(环境变量 CONNECT_API_KEY)、-i/--insecure(环境变量 CONNECT_INSECURE,用于自签名 TLS)、-c/--cacert <file>(环境变量 CONNECT_CA_CERTIFICATE)。

-n 和 CONNECT_SERVER 不能同时使用。posit-cli 会拒绝同时使用已保存的服务名称(-n/--name)和服务 URL 的命令,包括从环境变量中获取的 URL:-n/--name (from COMMANDLINE) cannot be specified in conjunction with options -s/--server (from ENVIRONMENT)。

只有服务标志会冲突。CONNECT_API_KEY、CONNECT_INSECURE 和 CONNECT_CA_CERTIFICATE 可以与 -n 一起使用,不会报错,因为密钥不属于互斥项。导出了 CONNECT_API_KEY 时,-n dogfood 是有效命令。必须移除的是 CONNECT_SERVER。

应根据请求中指定的内容选择方式,而不是根据当前导出的环境变量:

  • 请求指定了已保存的服务(“部署到 dogfood”)——使用 -n dogfood,并在该命令运行时执行 unset CONNECT_SERVER。用另一种方式解决冲突会更糟:CONNECT_SERVER 可能指向完全不同的服务,因此若为了保留它而省略 -n,就会部署到用户未指定的服务。
  • 请求未指定服务,即常见的无头运行——让 CONNECT_SERVER 和 CONNECT_API_KEY 提供目标服务,并使用 posit connect deploy <framework> <dir> 进行部署。

CONNECT_SERVER 不是机密信息。如果不确定它指向哪个服务,可以打印其值,并在报告中注明部署到的服务。

R(rsconnect)

先用本地昵称注册服务,再在该服务下注册用户:

library(rsconnect)

# 1. The server (once per server; the name is a local nickname)
rsconnect::addServer(url = "https://connect.example.com", name = "myserver")

# 2a. Interactive — approve in a browser, no key to handle
rsconnect::connectUser(server = "myserver")

# 2b. Or non-interactively (CI), only when the user asked for a key route
rsconnect::connectApiUser(
  server  = "myserver",
  account = "your-username",
  apiKey  = Sys.getenv("CONNECT_API_KEY")
)

connectCloudUser() 会对 Connect Cloud 进行身份验证;它是另一项服务,因此不能用于 Connect 服务。在此处请使用 connectUser() 或 connectApiUser()。

如果无法使用登录方式

报告问题并停止。说明你尝试注册的服务名称,以及失败的登录命令。不要搜索环境变量、.env 文件或凭据存储来寻找密钥填补缺口,也不要向用户索要密钥。下一步由用户决定。

评论

支持 Markdown