首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Symfony缓存:在构建码头容器时还是第一次运行时清除?

Symfony缓存:在构建码头容器时还是第一次运行时清除?
EN

Stack Overflow用户
提问于 2020-04-20 20:07:53
回答 1查看 4.7K关注 0票数 1

我在码头里装了一个symfony-3应用程序。

目前,我正在复制一个完整的parameters.yml,它具有构建ARG的功能,所以我可以使用3个不同的配置文件创建3个不同的构建:develpreprod

我已经知道,正确的方法是为所有环境创建一个单独的构建,因此是一个编译的映像二进制,然后在启动容器时通过ENV传递所有的配置。但我现在需要复制配置。

我的Dockerfile快结束了:

代码语言:javascript
复制
ARG ENVIRONMENT

# Copy the config file.
COPY config/tighten-violet.parameters.${ENVIRONMENT}.yml /files/tighten-violet/app/config/parameters.yml

# Build the composer part
RUN \
    cd /files/tighten-violet && \
    composer --no-ansi --no-interaction install --no-progress  --no-autoloader --no-scripts && \
    composer --no-ansi --no-interaction dump-autoload --no-dev --optimize --classmap-authoritative --no-scripts && \
    composer --no-ansi --no-interaction run-script --no-dev symfony-scripts && \
    php bin/console cache:clear && \
    php bin/console cache:clear --env=prod && \
    php bin/console assetic:dump --env=prod && \
    :

EXPOSE 80

# Start apache
CMD [ "apachectl", "-D", "FOREGROUND" ]

碰巧“构建器”主机不提供到生产数据库的连接.现在我感到惊讶的是,在清除缓存时,我看到了到数据库的“真正的连接”。我认为缓存只与编译自动加载程序、编译服务容器等“静态代码解析”有关.

我知道这个错误:

代码语言:javascript
复制
Updating the "app/config/parameters.yml" file
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::buildBootstrap
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache

 // Clearing the cache for the dev environment with debug
 // true

 [OK] Cache for the "dev" environment (debug=true) was successfully cleared.

  [Doctrine\DBAL\Exception\ConnectionException]
  An exception occured in driver: SQLSTATE[HY000] [2002] Connection timed out

  [Doctrine\DBAL\Driver\PDOException]
  SQLSTATE[HY000] [2002] Connection timed out

  [PDOException]
  SQLSTATE[HY000] [2002] Connection timed out

cache:clear [--no-warmup] [--no-optional-warmers] [-h|--help] [-q|--quiet] [-v|vv|vvv|--verbose] [-V|--version] [--ansi] [--no-ansi] [-n|--no-interaction] [-e|--env ENV] [--no-debug] [--] <command>

Script Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache handling the symfony-scripts event terminated with an exception

[...]

因此,看来symfony-scripts运行Sensio,而这个绑定又因为任何原因而试图执行真正的连接。

问题

如果我想将一个完全配置的symfony-3应用程序封装到一个坞内,我应该在构建时运行脚本吗?或者我应该以某种方式运行它们,作为运行的入口点脚本的一部分,首先运行脚本,然后启动apache?

EN

回答 1

Stack Overflow用户

发布于 2020-04-21 17:57:43

解决方案是将作曲家部分分成两个单独的块:

编写器指令第1部分

下载软件包的部分。这可以在“构建者”内部运行。

编写器指令第2部分

使用下载的软件包对系统进行热身的部分。这可以在运行的容器中运行,该容器将被运行“就位”,因此考虑到环境和访问适当的支持服务。

实现

Dockerfile

这样,我将Dockerfile中的RUN命令更改为

代码语言:javascript
复制
RUN \
    cd /files/tighten-violet && \
    composer --no-ansi --no-interaction install --no-progress  --no-autoloader --no-scripts && \
    composer --no-ansi --no-interaction dump-autoload --no-dev --optimize --classmap-authoritative --no-scripts && \
    composer --no-ansi --no-interaction run-script --no-dev symfony-scripts && \
    php bin/console cache:clear && \
    php bin/console cache:clear --env=prod && \
    php bin/console assetic:dump --env=prod && \
    :

转到

代码语言:javascript
复制
RUN \
    cd /files/tighten-violet && \
    composer --no-ansi --no-interaction install --no-progress  --no-autoloader --no-scripts && \
    :

ie:除了“将软件包下载到/vendor”之外,我删除了所有内容,因为“下载”不依赖于环境变量或配置。

到目前为止,我有一个可移植的码头图像与/vendor已经被填充。

但还差一步..。那些缺失的线去哪了?

bootstrap.sh

我所做的是一个引导脚本,所以我将CMD行从

代码语言:javascript
复制
CMD [ "apachectl", "-D", "FOREGROUND" ]

转到

代码语言:javascript
复制
CMD [ "/files/bootstrap.sh" ]

boostrap.sh文件在构建过程中也会被复制.下面是内容(简单的初始版本):

代码语言:javascript
复制
#!/usr/bin/env bash

# Provision
composer --no-ansi --no-interaction dump-autoload --no-dev --optimize --classmap-authoritative --no-scripts && \
composer --no-ansi --no-interaction run-script --no-dev symfony-scripts
php bin/console cache:clear && \
php bin/console cache:clear --env=prod && \
php bin/console assetic:dump --env=prod

# Start the server
apachectl -D FOREGROUND

这包含可能依赖于环境的“安装部分”,包括自动卸载、SensioBundle脚本以及缓存和转储。以防有ENV vars改变我们想要缓存的行为。

这恰好适用于docker run。但是,如果您执行docker stop,然后再次执行docker start,则供应部分也会一次又一次地运行(stop+start不冻结流程状态,就像“暂停”一样,它会终止进程,然后重新启动它,从bootstrap.sh开始重新启动。

因此,我可以改进引导脚本,使它标志,如果它已经自动提供。这是改进的(也是最后的) bootstrap.sh脚本的第二个版本:

代码语言:javascript
复制
#!/usr/bin/env bash

provisionIfNeeded()
{
    PROVISIONED=/tmp/provisioned
    if [ ! -f ${PROVISIONED} ]; then

        echo "------------------------------------------------------------------------------"
        echo "Provisioning"
        echo "------------------------------------------------------------------------------"

        composer --no-ansi --no-interaction dump-autoload --no-dev --optimize --classmap-authoritative --no-scripts && \
        composer --no-ansi --no-interaction run-script --no-dev symfony-scripts
        php bin/console cache:clear && \
        php bin/console cache:clear --env=prod && \
        php bin/console assetic:dump --env=prod

        echo "------------------------------------------------------------------------------"
        echo "Ended provisioning"
        echo "------------------------------------------------------------------------------"

        touch ${PROVISIONED}
    fi
}

startServer()
{
    echo "Starting httpd."
    exec apachectl -D FOREGROUND

    # If you do all (including provisioning) with an
    # unprivileged user, then do this:
    # exec sudo --preserve-env apachectl -D FOREGROUND
}

provisionIfNeeded
startServer

所以,在docker run

脚本启动,并在需要时尝试执行一项规定。Dockerfile.

  • On

  • 测试标志。如果没有找到,则调用配置的结束中缺少的行,将容器标记为provisioned.
  1. Then启动apache.

docker start

  1. 脚本启动,如果需要,尝试执行一项规定。找到标志
  2. ,因此不执行任何规定。
  3. 然后启动apache.

配置的10秒将从构建阶段中移出并移到运行阶段。

缺点

第一次启动容器只会比我们在构建阶段准备的时间多出10秒。

优点

容器与属于每个运行环境的缓存完全“编写”,同时通过Dockerfile保持构建阶段,以包含所有环境中的最大公共因素。

希望能帮上忙!

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61331153

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档