skip to Main Content

I want to use docker composer image in multistage Dockerfile for my Laravel application in order to reduce its size. The problem is that I need PHP 7.4 for my dependencies but the composer’s PHP is 8.1.1. Is there any way to customize this? If there’s no way to downgrade the PHP version of it, how can I reduce the size of my docker image and what should I use instead to install my project dependencies?

I tried installing dependencies with --ignore-platform-reqs flag but the app doesn’t work after the build.

FROM composer:latest

COPY database/ database/

COPY composer.json composer.json
COPY composer.lock composer.lock

RUN composer install

2

Answers


  1. I just ran into this recently and solved it with two steps.

    1. Tell composer to use a specified version of PHP using the platform config.
    2. Tell composer to not generate the autoload, and do it manually in your final image or an image running the correct version of PHP.

    This became a problem recently because, with PHP 8.1, the post-autoload-dump started throwing errors about Laravel’s Collection class. The post autoload script is running Laravel code, meaning even though we just installed dependencies for v 7.X, we’re executing the script with 8.1 still.

    There may be better ways to solve this, and if so please let me know!, but here is what I did.

    Updated composer.json to specify the platform:

    "config": {
      "platform": {
        "php": "7.3.33" // Or your specific version
      }
    },
    

    Tell composer to skip autoload generation:

    RUN composer install --no-autoloader
    

    And last, in my final image:

    RUN composer dump-autoload
    

    The downside here is you must have composer installed in your final image, which in a way defeats the purpose of splitting the jobs during the build.

    You may choose instead to follow the recommendation from the Composer docker image readme and include it this way, and ditch the multi-stage build altogether.:

    COPY --from=composer /usr/bin/composer /usr/bin/composer
    

    While I cannot confidently say there are not better options out there to address this problem, I hope this answer provides an explanation of why the problem exists, and points you in the right direction to solve it.

    Login or Signup to reply.
  2. The Composer image is going to use whatever the latest version of PHP currently is, so composer:latest will never get you 7.4. You could scan backwards through the old Composer docker images until you find the most recent one that is based on 7.4, and then use that specific version of the image.

    FROM composer:1.10.19
    

    Note however that you’ll never get updated versions of composer this way.

    Alternatively, if size is a concern then you could base your image on alpine:latest (which is tiny and currently uses 7.4 in its app repo) and then install PHP with apk add php-cli. This will give you an image of about 20mb, but sooner or later Alpine is going to update their base PHP to 8.0 and your image will break.

    Probably your best option would be to base your image on one of the explicitly-versioned PHP containers like php:7.4-cli-alpine and then install the latest Composer into that image. This will give you much better control over what version of PHP runs in your image, and it’ll be very easy to later copy this image to base it off 8.0 for upgrade testing.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search