如何为每个部署目标指定 Jenkins 部署配置

Posted

技术标签:

【中文标题】如何为每个部署目标指定 Jenkins 部署配置【英文标题】:How to specify Jenkins deployment config per deployment target 【发布时间】:2016-07-17 04:29:05 【问题描述】:

我是 Java 和 Jenkins 的新手,但拥有强大的 C# MVC、TFSBuild 和 Octopus Deploy 背景。 在 Octopus Deploy 中,可以读取 MVC Web.Config XML 文件并替换数据库连接字符串 - 这使得获取构建的工件并提升到不同的内部 VM 环境变得容易。我想用 Java 和 Jenkins 达到同样的效果。

我认为数据库的 Java 连接字符串可以/应该在每个 VM 环境的环境变量中设置是否正确? 是否有 Jenkins 插件可以为我实现这一点,还是我需要编写一个 PowerShell 脚本?

我找到了几个链接,例如CloudBees,但它们似乎都是针对云提供商的;我只想针对内部虚拟机。

使用 SpringBatch、Maven、数据库连接到 Oracle。

【问题讨论】:

你如何设置你的数据库连接?它存在于哪个文件中?您是否需要在构建阶段建立数据库连接。如果不是,为什么不将 jndi 用于可以为每个服务器单独设置的 DB 连接字符串。你是使用 maven 还是其他东西来构建你的 web 应用程序? 我是 Java 新手,存储数据库连接的好习惯在哪里,所以我愿意接受建议 这在很大程度上取决于您使用的框架以及您是否部署到应用服务器。 @andrepnh 说得好,我一直在阅读 ***.com/questions/8967558/… 以了解有关存储连接详细信息的选项的更多信息 @sgpalit 我正在使用 Maven 构建和 Spring 框架。 【参考方案1】:

您也可以尝试使用不同的 Maven 配置文件来构建适合测试的特定工件,但不建议这样做。您应该测试尽可能接近生产版本的系统版本。

所以,是的,环境变量是最便携的方法。一个强大的 Jenkins 插件来控制它们是EnvInject。您可以将特定变量定义为将在构建过程中注入的简单键值对。


编辑

由于您使用的是 Spring Batch,因此您可以使用 xml 文件或编程配置来设置数据库连接。配置文件只支持系统属性,所以你可以这样做:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="url" value="$db.url" />
    <property name="username" value="$db.user" />
    <property name="password" value="$db.password" />
    <!-- drivers and other stuff -->
</bean>

对于编程配置(您可以查看完整示例 here),您也可以使用系统属性:

@Bean
public DataSource someDataSource() throws SQLException 
    final SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
    dataSource.setUrl(System.getProperty("db.url"));
    dataSource.setUsername(System.getProperty("db.user"));
    dataSource.setPassword(System.getProperty("db.password"));
    // Driver, connection properties, if any, and other stuff
    return dataSource;

还有环境变量:

dataSource.setUrl(System.getenv("db.url"));
dataSource.setUsername(System.getenv("db.user"));
dataSource.setPassword(System.getenv("db.password"));

您可以使用 EnvInject 插件设置环境变量,但如果您使用系统属性,最简单的传递它们的方法是作为命令行参数:java ... -Ddb.url=something -Ddb.user=foo -Ddb.password=bar。但是请注意,任何能够列出该 java 进程的人都可以访问 db 凭据。如果你坚持使用属性,你也可以使用属性文件来传递它们,Spring seems to support。问题是您必须为每个环境维护单独的配置文件,我认为这会增加可能更简单的构建过程的大量开销。

【讨论】:

【参考方案2】:

由于您没有具体说明您的数据库是什么以及您的服务器是什么,我将给出一个关于 tomcat、mysql 和 spring 配置的示例。关于tomcatjndi-datasource-examples的更多信息,你应该将你的sql驱动添加到tomcat的lib中。

在您可以在 tomcat_root/conf 文件夹下找到的 server.xml 中,在上下文中添加您的连接字符串

<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
           maxActive="100" maxIdle="30" maxWait="10000"
           username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver"
           url="jdbc:mysql://localhost:3306/javatest"/>

在您的 web.xml 中添加以下资源引用

<resource-ref>
  <description>DB Connection</description>
  <res-ref-name>jdbc/TestDB</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
</resource-ref>

在你的spring配置中添加以下

<beans:bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <beans:property name="jndiName" value="java:comp/env/jdbc/TestDB"/>
</beans:bean>

现在您可以自动装配或添加数据源 bean 作为其他数据服务 bean 的引用。

@Autowired
private DataSource dataSource;

【讨论】:

以上是关于如何为每个部署目标指定 Jenkins 部署配置的主要内容,如果未能解决你的问题,请参考以下文章

具有多个部署的单个 Jenkins 作业

Swift - 你如何为你的 iOS 应用决定最佳的“部署目标”

如何为包含空格的 Jenkins 环境变量指定值

如何为 Cloud Build 用于 Cloud Run 部署的 Cloud Storage 存储分区指定区域?

如何为指定的部署路径制作mtd-utils 2.0

如何为 Jenkins 管道中的失败阶段实施重试选项?