如何从 php 容器中的 dockerfile 运行 composer install

Posted

技术标签:

【中文标题】如何从 php 容器中的 dockerfile 运行 composer install【英文标题】:How run composer install from dockerfile in php container 【发布时间】:2019-04-04 08:50:33 【问题描述】:

美好的一天,我在 Dockerfile 中设置了 php 容器

我正在尝试使用此命令运行 composer install

WORKDIR '/app'
RUN curl -sS https://getcomposer.org/installer | \
            php -- --install-dir=/usr/bin/ --filename=composer
        CMD bash -c "composer install && php artisan serve --host 0.0.0.0 --port 80"
    EXPOSE 80
    EXPOSE 22
    CMD ["php-fpm"]

但我没有收到错误,并且由于 composer install 没有工作而无法运行应用程序。只是 laravel 的白屏意味着未安装 composer。

如果我在 docker compose up 之后运行

docker run -it --rm -v $(pwd):/app composer/composer install

我收到一个错误 Composer 在 /app 中找不到 composer.json 文件 要初始化项目,请按照https://getcomposer.org/“入门”部分中的说明创建一个 composer.json 文件

如果我尝试复制项目目录,则会收到错误消息

COPY /var/www/docker/project /app

错误:服务“php”构建失败:复制失败:stat /var/lib/docker/tmp/docker-builder091462376/var/www/docker/project:没有这样的文件或目录 虽然我在 docker-compose.yml 的 php 容器中有卷

volumes:
            - $APP_PATH_HOST:$APP_PATH_CONTAINER
            - /app/vendor/

这是我的 docker-compose.yml

version: '2'
services:
    nginx:
     image: nginx:latest
     container_name: "$PROJECT_NAME_nginx"
     environment:
       NGINX_STATIC_OPEN_FILE_CACHE: "off"
       NGINX_ERROR_LOG_LEVEL: debug
       NGINX_BACKEND_HOST: php
       NGINX_VHOST_PRESET: php
       NGINX_SERVER_ROOT: /app/public
     ports:
        - "80:80"
        - "443:443"
     volumes:
        - ./hosts:/etc/nginx/conf.d
        - $APP_PATH_HOST:$APP_PATH_CONTAINER
        - ./logs:/var/log/nginx
     links:
        - php

     labels:
       - 'traefik.backend=nginx'
       - 'traefik.port=80'
       - 'traefik.frontend.rule=Host:$PROJECT_BASE_URL'  
    php:
        build: ./images/php
        links:
            - mariadb
        #command: bash -c 'cd /app composer install'    
        volumes:
            - $APP_PATH_HOST:$APP_PATH_CONTAINER
            - /app/vendor/

    mariadb:
     image: wodby/mariadb:$MARIADB_TAG
     container_name: "$PROJECT_NAME_mariadb"
     stop_grace_period: 30s
     environment:
      mysql_ROOT_PASSWORD: $DB_ROOT_PASSWORD
      MYSQL_DATABASE: $DB_NAME
      MYSQL_USER: $DB_USER
      MYSQL_PASSWORD: $DB_PASSWORD

    pma:
     image: phpmyadmin/phpmyadmin
     container_name: "$PROJECT_NAME_pma"
     ports:
        - "9000:80"
     environment:
       PMA_HOST: $DB_HOST
       PMA_USER: $DB_USER
       PMA_PASSWORD: $DB_PASSWORD
       PHP_UPLOAD_MAX_FILESIZE: 1G
       PHP_MAX_INPUT_VARS: 1G
     labels:
      - 'traefik.backend=pma'
      - 'traefik.port=80'
      - 'traefik.frontend.rule=Host:pma.$PROJECT_BASE_URL'

这里完全是 Dockerfile

FROM php:7.2-fpm-alpine3.6
WORKDIR '/app'
RUN apk update && apk upgrade\
    && apk add --no-cache curl libbz2 php7-bz2 php7-pdo php7-pgsql php7-bcmath php7-zmq php7-curl bash php7-pear php7-imagick openssh imap-dev\
    libtool \
    postgresql-dev \
    libpng-dev \
    imagemagick-c++ \
    imagemagick-dev \
    libmcrypt-dev \
    libxml2-dev \
    yaml-dev \
    bzip2 \
    aspell-dev \
    autoconf \
    build-base \
    linux-headers \
    libaio-dev \
    zlib-dev \
    git \
    subversion \
    freetype-dev \
    libjpeg-turbo-dev \
    libmcrypt-dev \
    bzip2-dev \
    libstdc++ \
    libxslt-dev \
    openldap-dev \
    hiredis-dev \
    make \
    unzip \
    ffmpeg \
    wget
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN docker-php-ext-configure imap --with-imap --with-imap-ssl \
  && docker-php-ext-install -j 4 imap 


RUN docker-php-ext-install gd bcmath zip bz2 pdo pdo_mysql simplexml opcache sockets mbstring pcntl xsl pspell
RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ 
RUN pecl install imagick
RUN docker-php-ext-enable imagick 
RUN pecl install xdebug
RUN wget http://xdebug.org/files/xdebug-2.6.1.tgz
RUN tar -xvzf xdebug-2.6.1.tgz
RUN cd xdebug-2.6.1 \
    && phpize \
    && ./configure --enable-xdebug \
    && make \
    && make install \
    && cp modules/xdebug.so /usr/local/lib/php/extensions/no-debug-non-zts-20170718 \
    && echo 'zend_extension = /usr/local/lib/php/extensions/no-debug-non-zts-20170718/xdebug.so' >> /usr/local/etc/php/php.ini \
    && echo 'zend_extension = /usr/local/lib/php/extensions/no-debug-non-zts-20170718/xdebug.so' >> /etc/php7/php.ini \
    && echo 'xdebug.remote_enable=true' >> /etc/php7/php.ini \
    && echo 'xdebug.remote_host=127.0.0.1' >> /etc/php7/php.ini \
    && echo 'xdebug.remote_port=9000' >> /etc/php7/php.ini \
    && echo 'xdebug.remote_handler=dbgp' >> /etc/php7/php.ini \
    && echo 'xdebug.max_nesting_level=512' >> /etc/php7/php.ini

ENV COMPOSER_ALLOW_SUPERUSER 1

RUN echo "Install ZeroMQ library and PHP extension"
RUN apk add --update autoconf gcc libzmq zeromq-dev zeromq coreutils build-base
RUN pecl install zmq-beta \
  && docker-php-ext-enable zmq
#COPY ./project /app
RUN curl -sS https://getcomposer.org/installer | \
    php -- --install-dir=/usr/bin/ --filename=composer
#RUN "composer install"


EXPOSE 80

EXPOSE 22
#CMD php artisan serve --host=0.0.0.0 --port=80
#CMD php artisan migrate --seed

CMD ["php-fpm"]
USER root
copy run.sh /run.sh
RUN chmod +x /run.sh  
RUN ls
#RUN ["chmod", "+x", "/run.sh"]
COPY ./././project app/
RUN composer install --no-dev --no-interaction -o

CMD ["/run.sh"]

【问题讨论】:

Dockerfile 中使用的基本图像是什么? 我将 Dockerfile 添加到问题列表中 【参考方案1】:

您似乎正在混合 PHP-FPM 和独立的 PHP 服务器。 而是将 artisan serve 移动到 CMD。 还有,你只能有一个CMD,也就是容器启动时需要执行的命令。为了在构建容器时执行其他命令,需要使用RUN 命令。所以你的 Dockerfile 可以是这样的:

WORKDIR '/app'
RUN curl -sS https://getcomposer.org/installer | \
            php -- --install-dir=/usr/bin/ --filename=composer

RUN "composer install"
EXPOSE 80
EXPOSE 22
CMD "php artisan serve --host 0.0.0.0 --port 80"

【讨论】:

在您的情况下,我收到错误 /bin/sh: composer install: not found ERROR: Service 'php' failed to build: The command '/bin/sh -c "composer install"' 返回非零代码:127 您是在构建镜像,还是尝试运行已经构建的镜像?您的示例是需要构建到映像中的 Dockerfile,但您的命令 docker run ... composer/composer 运行现有映像。所以为了使用你的配置,你需要先从 Dockerfile 配置构建镜像 我在这个 Dockerfile 中构建图像,在这个 Dockerfile 中我试图运行 composer install 但收到错误。这是一个 php 容器。当我进入 php 容器并手动运行 composer install 一切都是很好/但不是我需要的 dockerfile 构建镜像时,您的项目需要在容器中可用。所以你需要一个ADD ... 命令将你的项目添加到容器中,否则没有什么可以运行composer install 当我尝试 COPY 时收到错误 COPY /var/www/docker/project /app ERROR: Service 'php' failed to build: COPY failed: stat /var/lib/docker/tmp /docker-builder091462376/var/www/docker/project: 没有这样的文件或目录

以上是关于如何从 php 容器中的 dockerfile 运行 composer install的主要内容,如果未能解决你的问题,请参考以下文章

如何在 php docker 容器上安装/启用 pdo-odbc 驱动程序?

调试 Dockerfile - 每天5分钟玩转 Docker 容器技术(15)

调试 Dockerfile - 每天5分钟玩转 Docker 容器技术(15)

Dockerfile的HEALTHCHECK指令

第 3 章 镜像 - 015 - 调试 Dockerfile

Dockerfile 用于创建一个图像以在 jenkins 中用作容器从站