为什么我的作曲家依赖项在 docker 容器中找不到,而是在我的 Mac 上本机?



在我的php应用程序中,我有几个通过作曲家安装的依赖项。当我在 mac 机器上本机构建此应用程序时,所有 php 依赖项都已正确安装。当应用程序运行时:命名空间,文件和类都可以通过作曲家的自动加载器找到。

但是,我希望在 docker 容器中运行此应用程序,以便我可以将容器推送到 ECS。当我在容器内运行相同的应用程序(在我的 Mac 上本机运行)时。作曲家的自动加载器找不到某个类,而是抛出如下异常:PHP Fatal error: Uncaught Error: Class ... not found in ....

真正奇怪的部分是,正确的命名空间显示在vendor/composer/autoload_psr4.php中(没有丢失),并且类文件确实存在于 docker 容器中的供应商目录中。

我能找到的唯一解决方案(让作曲家找到类)是删除供应商的目录并重新运行composer installdocker 容器中的所有目录。但我不想这样做。我应该能够在构建后将容器发布并部署到 ECS,而无需再次安装我的作曲家依赖项。我也尝试在入口点运行composer dump-autoloader,但这并没有解决我的问题。

以前有没有人遇到过这样的问题:php、comper 和 docker?

以下是一些有用的文件:

Dockerfile

FROM ubuntu:xenial
# install dependencies
RUN apt-get update
RUN apt-get install -y software-properties-common python-software-properties
RUN apt-get install -y language-pack-en-base
RUN LC_ALL=en_US.UTF-8 add-apt-repository ppa:ondrej/php
# setup nginx and PHP
RUN apt-get update && 
apt-get install -y nginx 
php7.1 
php7.1-fpm 
php7.1-cli 
php7.1-common 
php7.1-json 
php7.1-opcache 
php7.1-mysql 
php7.1-mbstring 
php7.1-gd 
php7.1-imap 
php7.1-ldap 
php7.1-dev 
php7.1-intl 
php7.1-gd 
php7.1-curl 
php7.1-zip 
php7.1-xml 
php-redis
# change the configuration to disable clear_env
RUN sed -e 's/;clear_env = no/clear_env = no/' -i /etc/php/7.1/fpm/pool.d/www.conf
# set up composer (we don't checksum the setup script)
ENV COMPOSER_HOME /opt/composer
RUN mkdir $COMPOSER_HOME && 
cd $COMPOSER_HOME && 
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && 
php composer-setup.php && 
php -r "unlink('composer-setup.php');" && 
rm keys.dev.pub && 
rm keys.tags.pub
COPY composer.sh /usr/bin/composer
RUN chmod 744 /usr/bin/composer
# download and install Symfony
RUN mkdir -p /usr/local/bin && 
curl -LsS https://symfony.com/installer -o /usr/local/bin/symfony && 
chmod a+x /usr/local/bin/symfony
ARG VERSION
ENV VERSION $VERSION
ENV WORK_DIR /opt/api
# copy everything to /opt/api
COPY . $WORK_DIR
RUN chmod a+x /opt/api/entrypoint.sh
# move the configuration file to the right place
RUN mv $WORK_DIR/nginx.conf /etc/nginx/sites-available/default
# fix the permissions for nginx and PHP
RUN chown -R www-data:www-data $WORK_DIR/var && 
chown -R www-data:www-data $WORK_DIR/app
# expose port 8000
EXPOSE 8000
# make it a working directory
WORKDIR $WORK_DIR
ENTRYPOINT ["/bin/sh", "/opt/api/entrypoint.sh"]

docker-compose.yml

app_api:
image: app/api:latest
command: run
links:
- redis
- mysql
ports:
- 8000:8000
env_file:
- ./app/config/parameters.env
environment:
DB_HOST: mysql
DB_PORT: 3306
DB_NAME: xxx
DB_USER: xxx
DB_PASSWORD: xxx
REDIS_HOST: redis
SECRET: xxx
ENVIRONMENT: dev
SUBENVIRONMENT: default
mysql:
image: mysql:5.7
expose:
- 3306
environment:
MYSQL_ROOT_PASSWORD: xxx
MYSQL_USER: xxx
MYSQL_PASSWORD: xxx
MYSQL_DATABASE: xxx
redis:
image: redis:alpine
expose:
- 6379

entrypoint.sh

#!/usr/bin/env bash
case $1 in
run)
echo "---> RUN app/api"
echo "clear_env = no" >> /etc/php/7.1/fpm/pool.d/www.conf
# start the PHP thing
/etc/init.d/php7.1-fpm start && 
# clear cache
composer dump-autoload && 
php bin/console cache:clear --env=prod && 
chown -R www-data:www-data var/cache/prod
# start the nginx in the foreground
nginx -g "daemon off;"
shift 1
;;

作曲家.json

{
"name": "app/api",
"license": "MIT",
"type": "project",
"autoload": {
"psr-4": { "": "src/" },
"classmap": [ "app/AppKernel.php", "app/AppCache.php" ]
},
"autoload-dev": {
"psr-4": {
"Tests\": "tests/"
}
},
"require": {
"php": ">=5.5.9",
"symfony/symfony": "3.1.*",
"doctrine/orm": "^2.5",
"doctrine/doctrine-bundle": "^1.6",
"doctrine/doctrine-cache-bundle": "^1.2",
"symfony/swiftmailer-bundle": "^2.3",
"symfony/monolog-bundle": "^2.8",
"symfony/polyfill-apcu": "^1.0",
"sensio/distribution-bundle": "^5.0",
"sensio/framework-extra-bundle": "^3.0.2",
"incenteev/composer-parameter-handler": "^2.0",
"crell/api-problem": "^2.0",
"prooph/service-bus-symfony-bundle": "^0.2.0",
"prooph/event-store-symfony-bundle": "^0.2.2",
"prooph/event-sourcing": "^4.0",
"prooph/event-store-doctrine-adapter": "^3.2",
"prooph/event-store-bus-bridge": "^2.0",
"doctrine/doctrine-migrations-bundle": "^1.2",
"nelmio/api-doc-bundle": "^2.13",
"prooph/snapshot-doctrine-adapter": "^1.1",
"mediamath/t1-php" : "^1.0.3",
"guzzlehttp/guzzle": "^5.3.1|^6.2.1",
"league/statsd": "^1.4",
"prooph/snapshotter": "^1.1",
"phpunit/phpunit": "^6.2.1"
},
"require-dev": {
"sensio/generator-bundle": "^3.0",
"symfony/phpunit-bridge": "^3.0"
},
"scripts": {
"symfony-scripts": [
"Incenteev\ParameterHandler\ScriptHandler::buildParameters",
"Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::buildBootstrap",
"Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache",
"Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::installAssets",
"Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::installRequirementsFile",
"Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::prepareDeploymentTarget"
],
"post-install-cmd": [
"@symfony-scripts"
],
"post-update-cmd": [
"@symfony-scripts"
]
},
"config": {
"platform": {
"php": "7.0.11"
}
},
"extra": {
"symfony-app-dir": "app",
"symfony-bin-dir": "bin",
"symfony-var-dir": "var",
"symfony-web-dir": "web",
"symfony-tests-dir": "tests",
"symfony-assets-install": "relative",
"incenteev-parameters": {
"file": "app/config/parameters.yml"
},
"branch-alias": {
"dev-master": "3.1-dev"
}
}
}

尝试使用以下 Dockerfile(安装 php 和 composer 之后的片段): WORKDIR $WORKDIR COPY composer.* ./ RUN composer install --no-autoloader COPY . ./ RUN composer dump-autoload 并将 vendor/添加到 .dockerignore 文件。

我认为这是构建具有由作曲家、npm、yarn 和类似包管理器控制的依赖项的 docker 映像的可取方法。

最新更新