我们正在使用Spring Boot开发Java后端服务。 application.properties文件具有数据库配置。我们正在4个不同的环境(开发,测试,UAT和生产)中进行部署。对于不同的环境,属性文件将有所不同。我们应该将这些文件保存在哪里?如何使用Jenkins进行升级?我们正在使用Apache Tomcat部署WAR文件。

现在我们将属性文件保存在C:\Program Files\Apache Software Foundation\Tomcat 7.0\conf目录中,并使用以下代码进行访问。每次我们在不同的环境中部署时,我们都需要替换各自的文件名application_test/uat/production.properties,提交代码并让Jenkins进行构建和部署。现在,我们必须手动将文件也保存在不同的环境中。

请提出建议。

#1 楼

我不同意@levi,您应该坚持使用12因子应用程序方法。将配置保留在仓库中。对密码的简单更改或小的设置都需要提交并重新构建管道。对于这么简单的事情,这太繁琐了。

我工作的最后3家公司都在使用“单一分支”存储库。只有master分支,而开发人员在此基础上创建“功能”分支。所有不同的环境都是从master构建的。在这种情况下,我们有一个静态配置文件,但是所有值都由构建管道注入。您可以从不同的来源获取它们:构建服务器环境变量,外部工具(Hashicorp Vault)或什至具有所有配置的另一个仓库(最后一个是最不希望的)。

#2 楼

典型的方法是在每个环境中使用包含名称相同的文件的文件夹:现在,您只需要确保在每个环境中都有一个定义为“ env”的操作系统环境变量已正确设置(即dev,test,uat)或产品)。您尚未说明如何启动应用程序(Linux上的j2ee服务器启动脚本?springboot docker容器?),但是在每个环境中设置环境变量应该不是问题。

除了可以从“ $ {catalina.base}”中加载文件之外,还可以使用以下方法从类路径中加载文件:

conf/dev/application.properties
conf/test/application.properties
conf/uat/application.properties
conf/prod/application.properties


如果您正在使用maven进行构建,则可以在src/main/resources下创建文件夹,这些文件夹将被复制到类路径中: Jenkins根本不需要做任何事情,因为可以在任何环境中运行相同的构建/发布工件。让Jenkins必须做额外的工作来重新配置应用程序以使其在特定环境中工作通常是一种反模式。相反,您应该以一个单一的Jenkins发布工作为目标,以构建可以在环境之间简单复制的工件。

这种方法有一个缺点。如果要创建新的环境,则必须将新文件添加到源代码管理中并创建新的发行产品。使用传统技术来设置新环境需要进行大量工作(例如,调试VM和数据库),因此向文件添加文件这一“额外步骤”似乎没有问题。

使用Kubernetes等更现代的云原生技术,您可以在几秒钟内按需设置环境。在这种情况下,您不想在代码库中预先指定环境。相反,您应该遵循12factor.net方法,并将每个属性定义为环境变量,并让spring直接使用它们。如果查看当前的springboot文档,则默认情况下使用环境变量。这意味着,如果您尚未定义@PropertySource,但使用的是类似的东西:

@PropertySource("file:${catalina.base}/conf/${env}/application.properties") 


它们将从相同名称的环境变量中设置,但使用大写。然后将问题转移到“我们如何确保在每个环境中正确设置环境变量”。易于在几秒钟内启动环境的技术(kubernetes,cloudfoundry,swarm)通常也使管理环境变量变得容易。使用kubernetes可以创建一个“ ConfigMap”(例如“ my-app-properties”),并将其挂载为环境变量,其中每个键和值都为应用程序定义了唯一的环境变量。每个逻辑环境然后可以是一个单独的Kubernetes命名空间(可能在开发/测试的共享集群上,而在prod的专用集群上)具有自己的“ my-app-properties”配置对象,该配置对象定义了该逻辑环境的环境变量。

您可以将这些设置置于源代码管理下,但不能置于应用程序源仓库中。相反,您可以采用“基础架构即代码”方法,其中运行应用程序的所有内容(例如,用于设置环境的所有脚本和yaml)都在其自己的git repo中。然后,您可以在配置库中设置由git webhook触发的配置部署作业。这样可以推出新的环境变量。这样,您就可以连续部署与应用程序代码的连续部署无关的配置更改。

如果您正在使用Kubernetes,那么Helmfile是一个绝佳选择,因为它不会更新git中未更改的kubernetes中的任何内容。这意味着每次推送到受保护的master分支时,都可以安全地重新应用git repo中的所有配置; helmfile将再次检查已部署的内容,仅更新需要更新的Kubernetes配置对象。

评论


我应该在特定的Kubernetes集群上添加该镜像,并使用我正在使用的容器映像,但是无法设置名为“ ENV”的环境变量,因此必须将其重命名为“ ENV_PREFIX”。我建议您使用环境变量专有的东西(例如三个字符的前缀),以避免内置环境变量或任何可能擦除或阻止某些变量的逻辑冲突。它还可以轻松过滤掉其他人的变量以查看您的变量。

–simbo1905
18-12-28 at 16:28

#3 楼

您可以为每个环境创建一个分支。因此,“ dev”分支将构建“ dev”应用并将其部署到“ dev”环境。

尽管根据12因素,您应该在应用程序存储库之外进行环境设置。尽管有时候这样做比打破该规则还需要更多的工作。