我有一个容器化的 Symfony 应用程序。
该过程的最后一步是预热缓存,以便图像可以“按原样”使用。虽然该命令显然工作正常,但最终结果是环境有两个缓存目录,一个具有正确的名称,另一个具有波浪号 (~)。
root@c238674823ae:/app/var/cache# ls -la
total 0
drwxr-xr-x 1 root root 16 Jan 2 11:46 .
drwxr-xr-x 1 root root 72 Jan 2 11:46 ..
drwxr-xr-x 1 root root 146 Jan 2 11:46 prod
drwxr-xr-x 1 root root 146 Jan 2 11:46 pro~
缓存目录中缺少一些名称“正确”的目录,这导致应用程序失败。
这些是预热缓存的 Dockerfile 步骤:
ENV COMPOSER_MEMORY_LIMIT=-1
RUN set -eux; \
mkdir -p var/cache var/log; \
composer dump-autoload -o --apcu --no-dev; \
composer dump-env prod; \
chmod +x bin/console; sync;
RUN set eux; \
rm -rf var/cache/* && \
bin/console cache:clear && \
bin/console assets:install public && \
bin/console importmap:install && \
bin/console sass:build -v && \
bin/console asset-map:compile;
如果我手动执行
rm -rf var/cache/prod && mv var/cache/pro~ var/cache/prod
,应用程序可以正常工作...但我害怕依赖于此,因为这似乎不正常或预期的行为。
如果在应用程序启动并运行后,我运行
bin/console cache:clear
,现在应用程序可以运行,但这需要我们在部署新映像后运行命令,从而导致每次部署都会出现几秒钟的停机时间,这是不希望的。
为什么
cache:clear
命令无法正确完成?为什么如果没有正确完成,却没有错误地退出?
现在有些愚蠢的事情。如果我这样做(运行
cache:clear
两次):
RUN set eux; \
rm -rf var/cache/* && \
bin/console cache:clear && \
bin/console cache:clear && \
bin/console assets:install public && \
bin/console importmap:install && \
bin/console sass:build -v && \
bin/console asset-map:compile;
现在它可以工作了,并且有一个缓存目录:(
docker run -it web-api/env-prod:local ls -la var/cache
total 0
drwxr-xr-x 1 root root 8 Jan 2 12:11 .
drwxr-xr-x 1 root root 72 Jan 2 12:11 ..
drwxr-xr-x 1 root root 170 Jan 2 12:11 prod
之所以出现
pro~
目录,是因为 Symfony 创建了一个临时缓存目录 (pro~
),并在缓存预热过程完成后自动将其重命名为 prod
。这可确保应用程序永远不会使用部分写入的缓存。
如果
cache:clear
命令失败或在此过程中被中断,临时 pro~
目录可能会保留。第二次运行该命令通常会成功,因为它会覆盖或删除剩余的临时状态。
cache:warmup
而不是 cache:clear
来预热缓存。RUN rm -rf var/cache/* && \
bin/console cache:warmup && \
[ ! -d var/cache/pro~ ] || mv var/cache/pro~ var/cache/prod;
pro~
目录,防止运行时问题。