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

ivan2nn's avatar

docker laravel run composer after containers have started

I asked a question few days ago about preparing a laravel project in Docker with postgresql

(https://laracasts.com/discuss/channels/laravel/docker-laravelpostgresql-translation-to-hostname)

Everything worked well (thanks to the answer I get).

The yaml file is this one:

version: '3'

services:

nginx:
    image: nginx:stable-alpine
    container_name: nginx
    ports:
        - "8080:80"
    volumes:
        - ./src:/var/www/html
        - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on: 
        - php
        - database

database:
    build:
        context: ./postgresql
        dockerfile: Dockerfile.db
    container_name: postgresql
    environment:
        - POSTGRES_HOST_AUTH_METHOD=trust
        - POSTGRES_USER=XXXX
        - POSTGRES_PASSWORD=XXXX
        - POSTGRES_DB=XXXX
    restart: always
    tty: true
    ports: 
        - "5433:5432"
    

php:
    build:
        context: ./php
        dockerfile: Dockerfile
    container_name: php
    volumes:
        - ./src:/var/www/html
    ports:
        - "9000:9000"

Now that everything is working i thought about using GitHub to make some tests and change only the project section. My .gitignore is like this one:

src/vendor
src/node_modules
src/public/storage
src/Homestead.yaml
src/Homestead.json
src/.env

Now when i pull the repo and do "docker-compose up -d --build", I get internal server error. Checking the logs I discovered that the vendor/autoload.php (and probably all the vendor files) is not present.

So i thought about running "composer install".

Now, my problem is that I don't know where and how to set that command.

Nginx starts only after php and postgresql has started. So where should i put the

RUN composer install

?? I tried inside the Dockerfile of the php

FROM php:7.2-fpm

RUN apt-get update && apt-get install -y libpq-dev
RUN docker-php-ext-install pdo pdo_pgsql pgsql
RUN ln -s /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini
RUN sed -i -e 's/;extension=pgsql/extension=pgsql/' /usr/local/etc/php/php.ini
RUN sed -i -e 's/;extension=pdo_pgsql/extension=pdo_pgsql/' /usr/local/etc/php/php.ini
RUN apt-get install -y nodejs npm
COPY --from=composer /usr/bin/composer /usr/bin/composer
RUN composer install
RUN npm install

but I get the error becasue it says it doesn't found var/www/html/composer.json.

So I thought that maybe I should run the composer command after nginx (the last container to start) has started.

Is there a way to achieve this?

0 likes
6 replies
Tray2's avatar

I have a image just for composer that I can call like this

docker-compose run --rm composer --version

The image looks like this

composer:
    image: composer:latest
    container_name: composer
    volumes:
      - ./src:/var/www/html
    working_dir: /var/www/html
    networks:
      - laravel
ivan2nn's avatar

ah, ok!... so where should i put it? Before calling nginx or after that? I mean, should i put:

depends on:
	nginx

And after i have an image how do i tell it to run composer install?

Do i create the dockerfile for it?

Tray2's avatar
Tray2
Best Answer
Level 73

Just put it in your docker-compose file.

Mine looks like this

version: '3.8'

networks:
  laravel:
    name: laravel

services:
  nginx:
    build:
      context: .
      dockerfile: nginx.dockerfile
    container_name: nginx
    depends_on: 
      - php
      - mysql
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./src:/var/www/html
    networks:
      - laravel

  php:
    build:
      context: .
      dockerfile: php.dockerfile
    container_name: php
    volumes:
      - ./src:/var/www/html
    networks:
      - laravel

  mysql:
    image: mysql:5.7.32
    container_name: mysql
    ports:
      - 3306:3306
    volumes:
      - ./mysql:/var/lib/mysql
    networks:
      - laravel
    environment: 
      MYSQL_DATABASE: laraveldb
      MYSQL_USER: laravel
      MYSQL_PASSWORD: secret
      MYSQL_ROOT_PASSWORD: secret

  composer:
    image: composer:latest
    container_name: composer
    volumes:
      - ./src:/var/www/html
    working_dir: /var/www/html
    networks:
      - laravel
  
  artisan:
    build:
      context: .
      dockerfile: php.dockerfile
    container_name: artisan
    volumes:
      - ./src:/var/www/html
    working_dir: /var/www/html
    entrypoint: ["php", "artisan"]
    networks:
      - laravel

  npm:
    image: node:13.7
    container_name: npm
    volumes: 
      - ./src:/var/www/html
    working_dir: /var/www/html
    entrypoint: ['npm']
    networks:
      - laravel

  phpunit:
    build:
      context: .
      dockerfile: php.dockerfile
    container_name: phpunit
    volumes:
      - ./src:/var/www/html
    working_dir: /var/www/html
    entrypoint: ["/var/www/html/vendor/bin/phpunit"]
    networks:
      - laravel

And to run composer install

docker-compose run --rm composer install
2 likes
ivan2nn's avatar

thank you Tray2.

It is not working, but only because I think the project was developed with Laravel 5.2 and the vendor files I have to recreate need an old Composer Version. Problem is I don't know which version of Composer I need to load into Docker.

ivan2nn's avatar

I tried also to upload the vendor folder to github but when I "docker-compose up" it gives me the following error:

*1 FastCGI sent in stderr: "PHP message: PHP Warning: require(/var/www/html/bootstrap/../vendor/autoload.php): failed to open stream: No such file or directory in /var/www/html/bootstrap/autoload.php on line 17

The strange thing is that I have a folder with the working laravel+nginx docker. If i copy the entire folder inside another folder (so the exact same structure) I get this error:

file_put_contents(/var/www/html/storage/framework/views/370c6bf25b91fa287e800b2ca0d47ef59c8e5dbe.php): failed to open stream: Permission denied

Even if I do a sudo chmod 777 for storage and database folders inside 'src' folder before launching "docker-compose", the problem remains

Please or to participate in this conversation.