如何将Lucene索引文件夹加入Play 2.7.x与Heroku的标准路径?
你的核心需求是让Heroku在部署时将项目根目录下的lucene-index文件夹包含到应用包中,和app、public同级,这个问题可以通过调整sbt构建配置来解决——因为Heroku是基于sbt的stage任务来构建和部署Play应用的。以下是具体步骤:
1. 确保lucene-index已提交到Git
首先确认你的.gitignore文件没有排除lucene-index文件夹,否则Heroku无法获取到这个目录的内容。如果之前有忽略规则(比如lucene-index/或者*.index),请将其移除,然后执行git add lucene-index/和git commit提交该目录。
2. 修改build.sbt配置,添加目录映射
Play框架使用sbt的Universal插件来生成发布包,我们需要配置该插件将lucene-index文件夹包含到发布包的根目录中。在你的build.sbt文件中添加以下代码:
// 将项目根目录下的lucene-index文件夹及其内容添加到发布包的根目录 mappings in Universal ++= directory(baseDirectory.value / "lucene-index")
这段代码的作用是告诉sbt:在构建通用发布包(也就是Heroku使用的包)时,把lucene-index目录下的所有文件和子目录都复制到发布包的根路径下,这样部署到Heroku后,该目录就会和app、public处于同一层级。
3. 本地验证配置是否生效
在部署到Heroku之前,可以先在本地验证配置是否正确:
- 运行
sbt stage命令构建应用 - 查看
target/universal/stage目录,你应该能看到lucene-index文件夹已经被复制到这里,里面的索引文件也完整存在
如果本地验证通过,那么Heroku部署后也会保留这个目录结构。
4. 应用启动逻辑的补充(可选)
你提到应用启动时会检查目录是否存在,本地环境生成索引,Heroku环境直接使用。这里可以利用Play的环境模式来判断:
import play.api.Environment import org.apache.lucene.store.{FSDirectory, Directory} import java.io.File class IndexService(env: Environment) { val indexDir = new File(env.rootPath.getAbsolutePath, "lucene-index") // 本地开发环境下如果目录不存在则生成索引 if (env.mode == play.api.Mode.Dev && !indexDir.exists()) { // 调用你的索引生成逻辑 generateLuceneIndex(indexDir) } // 打开Lucene索引目录 val luceneDir: Directory = FSDirectory.open(indexDir.toPath) }
通过env.rootPath可以获取到应用的根目录路径,确保在本地和Heroku环境下都能正确定位到lucene-index。
这样配置后,Heroku就会将你的lucene-index文件夹打包进应用,满足你无需放入conf目录的需求。
内容的提问来源于stack exchange,提问作者SkyWalker

