Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

siyabdev's avatar

Docker: PHP version conflicts with Composer's PHP version

I am running my laravel app using Docker. My app requires PHP version 8.2 and i set up my PHP container to use the same version but while installing dependencies, the composer uses PHP version 8.3 which is confusing to me because i never installed PHP 8.3 neither in the container nor on my host machine. From where composer takes this version?

My php.dockerfile:

FROM php:8.2-fpm-alpine

ARG UID
ARG GID

ENV UID=${UID}
ENV GID=${GID}

RUN mkdir -p /var/www/html/public
WORKDIR /var/www/html

RUN apk add --no-cache \
    libpng-dev \
    libjpeg-turbo-dev \
    libzip-dev \
    freetype-dev \
    zip \
    unzip \
    git \
    && rm -rf /var/cache/apk/*

RUN addgroup -g ${GID} --system laravel
RUN adduser -G laravel --system -D -s /bin/sh -u ${UID} laravel

RUN sed -i "s/user = www-data/user = laravel/g" /usr/local/etc/php-fpm.d/www.conf
RUN sed -i "s/group = www-data/group = laravel/g" /usr/local/etc/php-fpm.d/www.conf

RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
        && docker-php-ext-install -j$(nproc) gd zip pdo pdo_mysql

CMD ["php-fpm", "-y", "/usr/local/etc/php-fpm.conf", "-R"]

composer.dockerfile:

FROM composer:latest

ARG UID
ARG GID

ENV UID=${UID}
ENV GID=${GID}

RUN addgroup -g ${GID} --system laravel
RUN adduser -G laravel --system -D -s /bin/sh -u ${UID} laravel

docker-compose.yml:

services:
  nginx:
    build:
      context: .
      dockerfile: nginx.dockerfile
    ports:
      - 8080:80
    volumes:
      - ./src:/var/www/html
    depends_on:
      - mysql
      - php
  mysql:
    image: mysql:8
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_USER: laravel
      MYSQL_PASSWORD: secret
      MYSQL_ROOT_PASSWORD: secret
    volumes:
      - ./mysql:/var/lib/mysql
  php:
    build:
      context: .
      dockerfile: php.dockerfile
      args:
        - UID=${UID:-1000}
        - GID=${GID:-1000}
    volumes:
      - ./src:/var/www/html
  composer:
    build:
      context: .
      dockerfile: composer.dockerfile
      args:
        - UID=${UID:-1000}
        - GID=${GID:-1000}
    volumes:
      - ./src:/var/www/html
    user: laravel
    working_dir: /var/www/html
  npm:
    image: node:current-alpine
    volumes:
      - ./src:/var/www/html
    entrypoint: ["npm"]
    working_dir: /var/www/html
  artisan:
    build:
      context: .
      dockerfile: php.dockerfile
      args:
        - UID=${UID:-1000}
        - GID=${GID:-1000}
    volumes:
      - ./src:/var/www/html
    working_dir: /var/www/html
    depends_on:
      - mysql
    entrypoint: ['php', "/var/www/html/artisan"]

Any suggestions on how to solve this will be highly appreciated.

0 likes
3 replies
LaryAI's avatar
Level 58

The issue you're encountering is due to the fact that the composer:latest image you are using in your composer.dockerfile might be based on a different PHP version than the one specified in your php.dockerfile. The composer:latest image could be using PHP 8.3, which is causing the version conflict.

To resolve this, you can create a custom Composer image that uses the same PHP version (8.2) as your application. Here's how you can modify your composer.dockerfile to ensure it uses PHP 8.2:

  1. Create a custom Composer Dockerfile based on PHP 8.2:
# composer.dockerfile
FROM php:8.2-cli-alpine

ARG UID
ARG GID

ENV UID=${UID}
ENV GID=${GID}

RUN apk add --no-cache \
    libzip-dev \
    unzip \
    git \
    && rm -rf /var/cache/apk/*

RUN addgroup -g ${GID} --system laravel
RUN adduser -G laravel --system -D -s /bin/sh -u ${UID} laravel

# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
  1. Update your docker-compose.yml to use the custom Composer image:
services:
  nginx:
    build:
      context: .
      dockerfile: nginx.dockerfile
    ports:
      - 8080:80
    volumes:
      - ./src:/var/www/html
    depends_on:
      - mysql
      - php
  mysql:
    image: mysql:8
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_USER: laravel
      MYSQL_PASSWORD: secret
      MYSQL_ROOT_PASSWORD: secret
    volumes:
      - ./mysql:/var/lib/mysql
  php:
    build:
      context: .
      dockerfile: php.dockerfile
      args:
        - UID=${UID:-1000}
        - GID=${GID:-1000}
    volumes:
      - ./src:/var/www/html
  composer:
    build:
      context: .
      dockerfile: composer.dockerfile
      args:
        - UID=${UID:-1000}
        - GID=${GID:-1000}
    volumes:
      - ./src:/var/www/html
    user: laravel
    working_dir: /var/www/html
  npm:
    image: node:current-alpine
    volumes:
      - ./src:/var/www/html
    entrypoint: ["npm"]
    working_dir: /var/www/html
  artisan:
    build:
      context: .
      dockerfile: php.dockerfile
      args:
        - UID=${UID:-1000}
        - GID=${GID:-1000}
    volumes:
      - ./src:/var/www/html
    working_dir: /var/www/html
    depends_on:
      - mysql
    entrypoint: ['php', "/var/www/html/artisan"]

By creating a custom Composer image based on PHP 8.2, you ensure that the PHP version used by Composer matches the PHP version used by your application, thus resolving the version conflict.

martinbean's avatar
Level 80

@siyabdev Composer by definition needs PHP to run, since it’s a PHP script itself. Therefore the composer Docker image will be built from a PHP base image, most likely latest, which is why it will be running as 8.3.

Instead of using the composer image directly, you should copy it into your application’s Docker image, and execute composer commands inside of that image as a “multi-stage” build.

So, inside your application’s Dockerfile:

# Copy Composer phar from composer Docker image
COPY --from=composer /usr/bin/composer /usr/bin/composer

# Run Composer instead this image (i.e. PHP 8.2)
RUN composer install
1 like

Please or to participate in this conversation.