Skip to content
Advertisement

Container cannot see the prebuilt vendor folder in it

My project is throwing the next error after restarting the docker container:enter image description here

Warning: require(/var/www/ /var/www/ /vendor/composer/./symfony/polyfill-php80/bootstrap.php): Failed to open stream: No such file or directory in ‘vendor/composer/autoload_real.php line 71

My Dockerfile:

FROM php:8.0-fpm

# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/project/

# Set working directory
WORKDIR /var/www/project

# Install dependencies
RUN apt-get update && apt-get install -y 
    build-essential 
    libpng-dev 
    libjpeg62-turbo-dev 
    libfreetype6-dev 
    locales 
    zip 
    jpegoptim optipng pngquant gifsicle 
    vim 
    unzip 
    git 
    curl 
    libicu-dev 
    libonig-dev 
    libzip-dev
# install node
RUN curl -sL https://deb.nodesource.com/setup_current.x | bash -
RUN apt-get install -y nodejs

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install extensions
RUN docker-php-ext-install pdo_mysql zip exif pcntl
RUN docker-php-ext-configure gd --enable-gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/
RUN docker-php-ext-install gd
RUN docker-php-ext-configure intl
RUN docker-php-ext-install intl
RUN pecl install xdebug && docker-php-ext-enable xdebug
RUN echo 'xdebug.client_port=9000' >> /usr/local/etc/php/php.ini
RUN echo 'xdebug.mode=debug' >> /usr/local/etc/php/php.ini
RUN echo 'xdebug.discover_client_host=true' >> /usr/local/etc/php/php.ini
RUN echo 'memory_limit = 4G' >> /usr/local/etc/php/conf.d/docker-php-memlimit.ini;

# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www

# Copy existing application directory permissions
COPY --chown=www:www . /var/www/project

RUN composer install
RUN npm install
RUN npm run dev

RUN php artisan storage:link

ENV PATH="vendor/bin:${PATH}"

# Change current user to www
USER www

RUN composer global require tightenco/tlint
ENV PATH="${PATH}:/home/www/.composer/vendor/bin"

# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]

My docker-compose:

...
project:
    build:
      context: ./project/.
      dockerfile: Dockerfile
    image: project:v0
    restart: unless-stopped
    tty: true
    environment:
      PHP_IDE_CONFIG: serverName=docker_project
      XDEBUG_CONFIG: remote_host=172.17.0.1
      SERVICE_NAME: project
      SERVICE_TAGS: dev
    volumes:
      - /var/www/project/vendor/
      - ./project:/var/www/project
      - ./project/.docker/php/local.ini:/usr/local/etc/php/conf.d/local.ini
    networks:
      - project-network
...

Inside container run ls vendor/symfony before restarting the container: enter image description here And after:enter image description here

The error is solving if remove the vendor directory and run composer install.

I’m not a Jedi of the Docker.

Thanks for any help/suggestion!

Advertisement

Answer

In your volume section, you are mounting the host machine folder ./project to your container’s /var/www/project:

    volumes:
      - /var/www/project/vendor/
      - ./project:/var/www/project
      - ./project/.docker/php/local.ini:/usr/local/etc/php/conf.d/local.ini

The vendor folder is built inside of you container by the RUN command. It’s probably still there. But when you run docker-compose up, you instructed it to mask whatever inside with your host’s ./project folder when running it. So the container don’t see anything that you built before hand.

My advice is to only mount the folder that you need to change from time to time. For example:

    volumes:
      - /var/www/project/vendor/
      # You're probably uploading files here
      - ./project/public/assets:/var/www/project/public/assets
      # Note: You might need to mount some other files / folders that changes
      - ./project/.docker/php/local.ini:/usr/local/etc/php/conf.d/local.ini

Then the container will properly use the prebuilt /vendor while storing the thing that you need to keep in host.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement