【发布时间】:2016-08-04 21:17:43
【问题描述】:
我正在尝试创建一个 dockerized symfony 应用程序。问题是 DI 容器是在 Docker 容器构建期间构建的,这意味着我无法真正将运行时参数注入其中。到目前为止,我的解决方案是清除容器入口点中的缓存,但我意识到在某些情况下这可能是一个相当繁重的操作,因此我在 AppKernel 中基于内核的引导函数创建了一个自定义编译函数:
/**
* Recompiles the container without warming up the whole cache.
*
* Can be called upon docker container start to inject custom parameters.
*/
public function compile()
{
// Load class cache
if ($this->loadClassCache) {
$this->doLoadClassCache($this->loadClassCache[0], $this->loadClassCache[1]);
}
// Initialize bundles to be able to parse configurations
$this->initializeBundles();
$class = $this->getContainerClass();
$cache = new ConfigCache($this->getCacheDir().'/'.$class.'.php', $this->debug);
$container = $this->buildContainer();
$container->compile();
$this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass());
}
现在将在每次 Docker 容器启动时(在应用程序启动之前)调用此函数。
这是一个安全的操作吗?我是否应该假设任何缓存加热器都可能依赖容器参数? (由于我只更改容器参数运行时,服务和其他一切都应该保持不变。
最初在 symfony 回购问题中提出:https://github.com/symfony/symfony/issues/19525
PR 到我的自定义存储库:https://github.com/webplates/symfony-standard/pull/42
【问题讨论】:
-
在 prod 环境中构建容器时运行 cache:clear / cache:warmup 还不够吗?然后再也不碰他们了?我不明白您的手动方法和空缓存目录之间的区别?
-
我的意思是:Symfony 内部也是如此。为什么要重新发明轮子?
-
缓存清除不是一个好主意,因为它可能是一个繁重的操作(正如我指出的那样)。将缓存目录留空或仅手动删除已构建的容器都会导致预热。在某些情况下,预热甚至可能需要一分钟,这在容器化基础架构中是不可接受的。
-
一般来说你的方法应该有效。我在非全栈应用程序中以这种方式手动按需创建容器。
-
我知道这个捆绑包,它不是终极解决方案。它将与参数解析一起使用,但它实际上并没有替换参数,容器仍然会从构建的缓存中公开参数。这里的问题是我是否应该期望预热依赖于容器参数(例如数据库详细信息)。