我在码头里装了一个symfony-3应用程序。
目前,我正在复制一个完整的parameters.yml,它具有构建ARG的功能,所以我可以使用3个不同的配置文件创建3个不同的构建:devel、pre和prod。
我已经知道,正确的方法是为所有环境创建一个单独的构建,因此是一个编译的映像二进制,然后在启动容器时通过ENV传递所有的配置。但我现在需要复制配置。
我的Dockerfile快结束了:
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" ]碰巧“构建器”主机不提供到生产数据库的连接.现在我感到惊讶的是,在清除缓存时,我看到了到数据库的“真正的连接”。我认为缓存只与编译自动加载程序、编译服务容器等“静态代码解析”有关.
我知道这个错误:
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?
发布于 2020-04-21 17:57:43
解决方案是将作曲家部分分成两个单独的块:
编写器指令第1部分
下载软件包的部分。这可以在“构建者”内部运行。
编写器指令第2部分
使用下载的软件包对系统进行热身的部分。这可以在运行的容器中运行,该容器将被运行“就位”,因此考虑到环境和访问适当的支持服务。
实现
Dockerfile
这样,我将Dockerfile中的RUN命令更改为
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 && \
:转到
RUN \
cd /files/tighten-violet && \
composer --no-ansi --no-interaction install --no-progress --no-autoloader --no-scripts && \
:ie:除了“将软件包下载到/vendor”之外,我删除了所有内容,因为“下载”不依赖于环境变量或配置。
到目前为止,我有一个可移植的码头图像与/vendor已经被填充。
但还差一步..。那些缺失的线去哪了?
bootstrap.sh
我所做的是一个引导脚本,所以我将CMD行从
CMD [ "apachectl", "-D", "FOREGROUND" ]转到
CMD [ "/files/bootstrap.sh" ]boostrap.sh文件在构建过程中也会被复制.下面是内容(简单的初始版本):
#!/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脚本的第二个版本:
#!/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.
。
在docker start上
。
配置的10秒将从构建阶段中移出并移到运行阶段。
缺点
第一次启动容器只会比我们在构建阶段准备的时间多出10秒。
优点
容器与属于每个运行环境的缓存完全“编写”,同时通过Dockerfile保持构建阶段,以包含所有环境中的最大公共因素。
希望能帮上忙!
https://stackoverflow.com/questions/61331153
复制相似问题