如何在容器中安装 Composer 依赖项?

sfa*_*oso 7 php composer-php docker docker-compose

我正在尝试做什么

我正在尝试对这个基于 CodeIgniter 4 构建的 php 应用程序进行 dockerize。该应用程序具有以下依赖项,这些依赖项通常通过 Composer 安装:

"require": {
    "php": "^7.3 || ^8.0",
    "myth/auth": "dev-develop",
    "codeigniter4/framework": "^4.1",
    "codeigniter4/translations" : "^4.0"
},
Run Code Online (Sandbox Code Playgroud)

项目结构组织如下:

docker
    database
    nginx
    php-fpm
    docker-compose.yml
src
    ... app files ...
tests
composer.json
Run Code Online (Sandbox Code Playgroud)

在里面docker-compose.yml我有一个名为的服务php-fpm,它将所有应用程序文件复制到公共/var/www/html目录nginx

php-fpm:
  container_name: boilerplate_app
  build:
    context: ./php-fpm
  volumes:
    - ../src:/var/www/html
Run Code Online (Sandbox Code Playgroud)

我需要做的是使用 Composer 安装应用程序依赖项。

我尝试过的

最初,我想在Dockerfile可用php-fpm文件夹中执行此操作:

FROM php:8.0.2-fpm-alpine

RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install mysqli    

# Install Composer
COPY --from=composer /usr/bin/composer /usr/bin/composer

RUN composer require --working-dir=../../ app/boilerplate

COPY ./config/php.ini /usr/local/etc/php/

CMD ["php-fpm"]

EXPOSE 9000
Run Code Online (Sandbox Code Playgroud)

本质上,我已经安装composer在容器中,然后尝试从composer.json项目根目录中可用的文件安装所有依赖项。

问题

不幸的是,当我运行命令时docker-compose up --build出现此错误:

当前目录(./composer.json)中不存在composer.json,这可能是导致以下异常的原因。

似乎容器无法访问该composer.json文件,或者我对路径参数做了一些不好的事情working-dir

因此,我想采用另一个解决方案,定义另一个容器docker-compose.yml,其中将作曲家实例分开:

composer:
  image: composer:2.0.9
  command: ["composer", "require", "app/boilerplate"]
  volumes:
    - /var/www/html
Run Code Online (Sandbox Code Playgroud)

这应该composer.json从根目录读取文件,然后应该通过命令安装所有依赖项composer require app/boilerplate,但同样会引发相同的错误:

Composer 无法composer.json/app.

这是完整的docker-compose.yml

version: '3'

services:
  php-fpm:
    container_name: boilerplate_app
    build:
      context: ./php-fpm
    volumes:
      - ../src:/var/www/html

  nginx:
    container_name: boilerplate_nginx
    build:
      context: ./nginx
    volumes:
      - ../src:/var/www/html
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/sites/:/etc/nginx/sites-available
      - ./nginx/conf.d/:/etc/nginx/conf.d
    ports:
      - "8881:80"
      - "8882:443"
    depends_on:
      - php-fpm

  database:
    container_name: boilerplate_db
    build:
      context: ./database
    environment:
      - MYSQL_DATABASE=boilerplate_db
      - MYSQL_ROOT_PASSWORD=test
      - MYSQL_USER=foo
      - MYSQL_PASSWORD=test
    volumes:
      - ./database/data.sql:/docker-entrypoint-initdb.d/data.sql

  composer:
    image: composer:2.0.9
    command: ["composer", "require", "app/boilerplate"]
    volumes:
      - /var/www/html
Run Code Online (Sandbox Code Playgroud)

这是composer.json文件:

{
    "name": "app/boilerplate",
    "description": "CodeIgniter4 Boilerplate based on AdminLTE 3 with user management, roles, permissions, ...",
    "require": {
        "php": "^7.3 || ^8.0",
        "myth/auth": "dev-develop",
        "codeigniter4/framework": "^4.1",
        "codeigniter4/translations" : "^4.0"
    },
    "require-dev": {
        "phpunit/phpunit": "^9.1",
        "fakerphp/faker": "^1.13"
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "autoload": {
        "psr-4": {
            "app\\boilerplate\\": "src"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "scripts": {
        "post-update-cmd": [
          "@composer dump-autoload"
        ],
        "test": "phpunit --colors=always -vvv"
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以做什么来解决这个问题?

文件夹结构图片预览:

在此输入图像描述

yiv*_*ivi 7

看来你有几个问题。

首先,您依赖于绑定安装。但这些在运行时可用,但在构建时不可用。

因此,您需要composer.*在运行之前将文件复制到 docker 映像composer install

然后,您会遇到麻烦,因为您将构建上下文移动到项目的子目录,这将使从父目录复制文件变得有问题。

首先,更改构建上下文,然后简单地引用Dockerfile构建项目所需的内容:

services:
  php-fpm:
    container_name: boilerplate_app
    build:
      dockerfile: ./php-fpm/Dockerfile
      context: .
    volumes:
      - ./src:/var/www/html
# the rest of your docker-compose.yml
Run Code Online (Sandbox Code Playgroud)

执行此操作后,您需要调整您的Dockerfile帐户,使其构建上下文现在是上一个目录,并添加所需的COPY语句。

我还更新了 dockerfile 以利用 Docker 多阶段进程

FROM composer:2 as composer_stage

RUN rm -rf /var/www && mkdir -p /var/www/html
WORKDIR /var/www/html

COPY composer.json composer.lock ./

# This are production settings, I'm running with 'no-dev', adjust accordingly 
# if you need it
RUN composer install --ignore-platform-reqs --prefer-dist --no-scripts --no-progress --no-interaction --no-dev --no-autoloader

RUN composer dump-autoload --optimize --apcu --no-dev

FROM php:8.0.2-fpm-alpine

WORKDIR /var/www/html

RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install mysqli

COPY php-fpm/config/php.ini /usr/local/etc/php/

COPY --from=composer_stage /var/www/html /var/www/html

COPY src src/

CMD ["php-fpm"]

EXPOSE 9000
Run Code Online (Sandbox Code Playgroud)

我还添加了一条COPY语句来复制您的项目src目录,因为否则您正在构建的图像具有您的作曲家依赖项,而没有其他任何东西。这样,您的应用程序就是一个适当的独立容器(没有双关语)。

您还应该确保src安装点。由于这些并不真正属于镜像构建,而仅在实际运行容器时使用,因此我没有非常仔细地审查它们。

对应用程序进行 Docker 化/容器化首先是构建正确的映像,然后您需要创建适当的使用文档