部署构建配置
当您的项目构建和测试完成后,您通常需要将其部署到最终的基础设施中。 例如,将一个包上传到 NuGet Gallery,将一个容器交付给 DockerHub 仓库,或者更新您的文档网站源码。 不同的 CI/CD 解决方案对于流程的最后一步使用了不同的术语:「部署」阶段、交付目标、发布、生产等等。
在 TeamCity 中,交付任务由执行常规构建例程的同一 "构建配置" 对象执行。 然而,由于构建和交付是由不同团队成员触发的不同任务,部署产品的配置可以被明确标记为 部署配置。
关键要点
部署配置旨在区分执行常规构建例程的配置与将应用程序交付给外部基础设施的配置。
部署配置在功能方面与常规配置无异。 他们可以使用相同的构建功能,使用相同的构建运行程序,等等。
如果部署配置遵循同一链中的常规构建 / 测试配置,具有足够权限的 TeamCity 用户可以直接从常规配置触发部署。
部署配置不允许运行个人构建。 此外,您不能同时运行属于同一部署配置的两个构建。
建议将部署和构建 / 测试配置分割为不同的子项目,以设置精细的用户权限。
要切换构建配置类型,请导航到 配置设置 | 常规 选项卡。
示例
在本教程中,您将创建部署配置以补充在 合成构建配置 文章中开发的管道。

创建建筑管道
遵循 合成构建配置 文章中描述的步骤,创建一个由五个相互连接的配置组成的链,以 "Build All" 组合配置作为终止。

创建部署子项目
能编辑和运行构建配置的常规项目开发者不应有权运行交付任务。 为了设置细粒度的用户权限,并将与交付相关的参数和凭证安全地存储在主构建管道之外,我们建议在一个单独的项目中创建交付配置。
转到 管理 | <您的项目> 并点击 创建子项目。
选择 手动 图块以创建一个与任何特定 VCS 存储库无关的空白项目。
将子项目名称设置为 "Deployment Configurations"。
根据您的项目类型和交付目标的不同,部署配置可能包括不同的步骤。 例如,您的配置可以使用 .NET 运行器执行 nuget push 命令,将包上传到 NuGet Gallery,或是上传文件到 FTP 服务器或 Windows 共享的一种 部署者。
在此示例中,部署配置将 Docker 镜像上传到 DockerHub 注册表。 因此,您需要创建一个 Docker connection 来指定注册表地址和您的登录凭证。 此连接将在此子项目的所有配置中可用。 要创建连接,请导航到子项目的 连接 选项卡。
以下的 Kotlin 代码展示了最终设置。
// Main Project
project {
buildType(Building_1) // The "Build All" configuration
subProject(BuildingConfigsProject) // The subproject with building configs
subProject(DeploymentConfigsProject) // Our new subproject for deployment
}
// ...
object DeploymentConfigsProject : Project({
name = "Deployment Configurations"
description = "This subproject contains configurations that perform delivery tasks"
features {
dockerRegistry {
id = "PROJECT_EXT_5"
name = "Docker Registry"
userName = "your_dockerhub_name"
password = "credentialsJSON:0ff181ee-cc10-48ac-b5f4-ce50ca2013b4"
}
}
})
添加您的第一个部署配置
在新子项目的 一般设置 选项卡上,点击 创建构建配置。
选择 手动 选项,并输入 "Deploy Console (Windows)"作为配置名称。
将构建配置类型设置为 "Deployment"。
在 版本控制设置 中,点击 附加 VCS 根 并选择所有 "Build..."配置使用的相同根目录。
"部署控制台(Windows)"依赖于 "构建控制台 & 网页(win-x64)"构建配置,并且必须能够访问其制品。
导航到 构建配置 | 依赖项 并添加相应的快照和工件(bin => 上下文 )依赖项。
由于我们需要上传生成的容器,所以添加 Docker 注册表连接 构建功能,该特性使用在 创建部署子项目 部分创建的 Docker 连接。
在您的配置中添加三个构建步骤:
步骤#1 ——Docker 运行器,用于拉取(或如果已经拉取,则更新)所需的 .NET Runtime 容器 镜像。
步骤#2 —— 使用 Docker 运行器,根据 context / console . windows . dockerfile 中的指令构建镜像。
步骤#3 —— 另一个 Docker runner 步骤,用于发布新构建的镜像。
最终的配置设置应该如下所示:
object DeploymentConfigsProject_DeployConsoleWindows : BuildType({
name = "Deploy Console (Windows)"
enablePersonalBuilds = false
type = BuildTypeSettings.Type.DEPLOYMENT
maxRunningBuilds = 1
vcs {
root(DslContext.settingsRoot)
}
steps {
dockerCommand {
name = "Pull container"
commandType = other {
subCommand = "pull"
commandArgs = "mcr.microsoft.com/dotnet/runtime:7.0"
}
}
dockerCommand {
name = "Build container"
commandType = build {
source = file {
path = "context/console.windows.dockerfile"
}
contextDir = "context"
platform = DockerCommandStep.ImagePlatform.Windows
namesAndTags = "username/clock-console:windows"
commandArgs = "--build-arg baseImage=mcr.microsoft.com/dotnet/runtime:7.0"
}
}
dockerCommand {
name = "Push container"
commandType = push {
namesAndTags = "username/clock-console:windows"
}
}
}
features {
dockerRegistryConnections {
loginToRegistry = on {
dockerRegistryId = "PROJECT_EXT_5"
}
}
}
dependencies {
dependency(Building_BuildConsoleWebWinX64) {
snapshot {
}
artifacts {
artifactRules = "bin => context"
}
}
}
requirements {
contains("teamcity.agent.os.name", "windows-server-2022")
}
})
运行配送配置
以上代码突出了部署构建配置的第一个独特功能:其默认设置与常规配置的设置有所不同。
部署构建配置的其他独特功能包括:
启动部署构建的按钮被称为 部署 ,而不是 运行。

您可以直接从产生这些构件的配置中部署构件。 打开已完成的常规构建的详细信息,并在“Deployments”部分下点击 部署。

当部署构建开始时,您可以从 "Deployments" 部分追踪其进度。 当部署完成时,将出现 重新部署 按钮。 这个按钮可以让您重新运行交付例程。

如果构建配置的工件已经部署,早些的构建会警告用户触发部署配置将会覆盖较新的交付物。

TeamCity 项目、配置和单个构建的 更改 和 更新日志 选项卡允许您点击修订号以查看每次更改的详细信息。 如果您的流水线有交付配置,则此更改详细信息页面会显示 部署 选项卡,允许您快速识别此更改首次交付的时间。

常规构建配置首先显示具有最新更改的构建。 部署配置按时间顺序排列其构建。
添加更多配送配置
导航到 "Deploy Console (Windows)"配置设置,并点击 操作 | 复制配置 以创建交付配置的三个副本。
将新的副本进行如下修改:
导航至父级(最顶层)项目,并在现有的 "Build All" 旁边创建一个新的无步骤配置。 将这个新配置称为 "Deploy All" ,并将其类型设定为 "Deployment"。
在 "Deploy All" 配置设置中,为所有四个单独的 "Deploy..." 配置添加快照依赖。
您最终应该得到四个独立的部署配置,以及在主项目级别上的两个配置,这样可以方便地运行所有建设和部署任务。

请注意,使用此设置,个别 "Build..." 配置构建的构建结果页面在其“部署”部分显示多个选项。 当构建完成后,您可以触发任何相关的部署目标。

所有 "Deploy..." 配置的最终设置如下。
object DeployAll : BuildType({
name = "Deploy All"
enablePersonalBuilds = false
type = BuildTypeSettings.Type.DEPLOYMENT
maxRunningBuilds = 1
dependencies {
snapshot(DeploymentConfigsProject_DeployConsoleLinux) {
}
snapshot(DeploymentConfigsProject_DeployConsoleWindows) {
}
snapshot(DeploymentConfigsProject_DeployWebLinux) {
}
snapshot(DeploymentConfigsProject_DeployWebWindows) {
}
}
})
object DeploymentConfigsProject_DeployConsoleWindows : BuildType({
name = "Deploy Console (Windows)"
enablePersonalBuilds = false
type = BuildTypeSettings.Type.DEPLOYMENT
maxRunningBuilds = 1
vcs {
root(DslContext.settingsRoot)
}
steps {
dockerCommand {
name = "Pull container"
commandType = other {
subCommand = "pull"
commandArgs = "mcr.microsoft.com/dotnet/runtime:7.0"
}
}
dockerCommand {
name = "Build container"
commandType = build {
source = file {
path = "context/console.windows.dockerfile"
}
contextDir = "context"
platform = DockerCommandStep.ImagePlatform.Windows
namesAndTags = "username/clock-console:windows"
commandArgs = "--build-arg baseImage=mcr.microsoft.com/dotnet/runtime:7.0"
}
}
dockerCommand {
name = "Push container"
commandType = push {
namesAndTags = "username/clock-console:windows"
}
}
}
features {
dockerRegistryConnections {
loginToRegistry = on {
dockerRegistryId = "PROJECT_EXT_5"
}
}
}
dependencies {
dependency(Building_BuildConsoleWebWinX64) {
snapshot {
}
artifacts {
artifactRules = "bin => context"
}
}
}
requirements {
contains("teamcity.agent.os.name", "windows-server-2022")
}
})
object DeploymentConfigsProject_DeployConsoleLinux : BuildType({
name = "Deploy Console (Linux)"
enablePersonalBuilds = false
type = BuildTypeSettings.Type.DEPLOYMENT
maxRunningBuilds = 1
vcs {
root(DslContext.settingsRoot)
}
steps {
dockerCommand {
name = "Pull runtime dependencies"
commandType = other {
subCommand = "pull"
commandArgs = "mcr.microsoft.com/dotnet/runtime-deps:7.0-alpine"
}
}
dockerCommand {
name = "Build container"
commandType = build {
source = file {
path = "context/console.linux.dockerfile"
}
contextDir = "context"
platform = DockerCommandStep.ImagePlatform.Linux
namesAndTags = "username/clock-console:ubuntu"
commandArgs = "--build-arg baseImage=mcr.microsoft.com/dotnet/runtime-deps:7.0-alpine"
}
}
dockerCommand {
name = "Push container"
commandType = push {
namesAndTags = "username/clock-console:ubuntu"
}
}
}
features {
dockerRegistryConnections {
loginToRegistry = on {
dockerRegistryId = "PROJECT_EXT_5"
}
}
}
dependencies {
dependency(Building_BuildConsoleWebLinuxX64) {
snapshot {
}
artifacts {
artifactRules = "bin => context"
}
}
}
requirements {
contains("teamcity.agent.os.name", "ubuntu-20.04")
}
})
object DeploymentConfigsProject_DeployWebWindows : BuildType({
name = "Deploy Web (Windows)"
enablePersonalBuilds = false
type = BuildTypeSettings.Type.DEPLOYMENT
maxRunningBuilds = 1
vcs {
root(DslContext.settingsRoot)
}
steps {
dockerCommand {
name = "Pull container"
commandType = other {
subCommand = "pull"
commandArgs = "mcr.microsoft.com/dotnet/runtime:7.0"
}
}
dockerCommand {
name = "Build container"
commandType = build {
source = file {
path = "context/web.windows.dockerfile"
}
contextDir = "context"
platform = DockerCommandStep.ImagePlatform.Windows
namesAndTags = "username/clock-web:windows"
commandArgs = "--build-arg baseImage=mcr.microsoft.com/dotnet/runtime:7.0"
}
}
dockerCommand {
name = "Push container"
commandType = push {
namesAndTags = "username/clock-web:windows"
}
}
}
features {
dockerRegistryConnections {
loginToRegistry = on {
dockerRegistryId = "PROJECT_EXT_5"
}
}
}
dependencies {
dependency(Building_BuildConsoleWebWinX64) {
snapshot {
}
artifacts {
artifactRules = "bin => context"
}
}
}
requirements {
contains("teamcity.agent.os.name", "windows-server-2022")
}
})
object DeploymentConfigsProject_DeployWebLinux : BuildType({
name = "Deploy Web (Linux)"
enablePersonalBuilds = false
type = BuildTypeSettings.Type.DEPLOYMENT
maxRunningBuilds = 1
vcs {
root(DslContext.settingsRoot)
}
steps {
dockerCommand {
name = "Pull runtime dependencies"
commandType = other {
subCommand = "pull"
commandArgs = "mcr.microsoft.com/dotnet/runtime-deps:7.0-alpine"
}
}
dockerCommand {
name = "Build container"
commandType = build {
source = file {
path = "context/web.linux.dockerfile"
}
contextDir = "context"
platform = DockerCommandStep.ImagePlatform.Linux
namesAndTags = "username/clock-web:ubuntu"
commandArgs = "--build-arg baseImage=mcr.microsoft.com/dotnet/runtime-deps:7.0-alpine"
}
}
dockerCommand {
name = "Push container"
commandType = push {
namesAndTags = "username/clock-web:ubuntu"
}
}
}
features {
dockerRegistryConnections {
loginToRegistry = on {
dockerRegistryId = "PROJECT_EXT_5"
}
}
}
dependencies {
dependency(Building_BuildConsoleWebLinuxX64) {
snapshot {
}
artifacts {
artifactRules = "bin => context"
}
}
}
requirements {
contains("teamcity.agent.os.name", "ubuntu-20.04")
}
})
设置用户权限
管理 | 用户管理 部分允许您为每个项目设置 用户角色和权限。 请参考下面的示例
在此设置中,Alice 可以触发构建和部署任务,而 Bob 无法启动交付。 当 Bob 浏览任何 "Build..." 配置的构建结果时,TeamCity 不会显示 "Deployments" 部分。
TeamCity 目前不允许您在构建配置范围内设置角色和权限。 因此,您无法设置权限,让 Bob 能够运行 "Build All" 构建,但阻止他们触发 "Deploy All" 构建。 为了解决这个问题,您需要将这些聚合配置移动到相应的子项目中。
最后修改日期: 2025年 9月 3日