skip to Main Content

I am trying to run php artisan migrate on docker compose but this error occur in my mysql container:

sh: php: command not found

docker-compose.yml

version: "3"
services:
    # Application & web server
    app:
        build:
            context: .
        working_dir: /var/www
        volumes:
            - ./:/var/www
        depends_on:
            - "mysql"
        ports:
            - 8001:80
    mysql:
        image: mysql:latest
        volumes:
            - dbdata:/var/lib/mysql
        environment:
            MYSQL_DATABASE: ${DB_DATABASE}
            MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
            MYSQL_PASSWORD: ${DB_PASSWORD}
        ports:
            - 3306:3306
        entrypoint: sh -c "sleep 30 && php artisan migrate"
    phpmyadmin:
        image: phpmyadmin:latest
        ports:
            - 9001:80
        environment:
            - PMA_ARBITRARY=1
#Docker Networks
networks:
    app-network:
        driver: bridge
#Volumes
volumes:
    dbdata:
        driver: local

Docker file

FROM php:8.0-apache

RUN apt-get update && apt-get install -y  
    libfreetype6-dev 
    libjpeg-dev 
    libpng-dev 
    libwebp-dev 
    --no-install-recommends 
    && docker-php-ext-enable opcache 
    && docker-php-ext-configure gd --with-freetype --with-jpeg 
    && docker-php-ext-install pdo_mysql -j$(nproc) gd 
    && apt-get autoclean -y 
    && rm -rf /var/lib/apt/lists/*

# Update apache conf to point to application public directory
ENV APACHE_DOCUMENT_ROOT=/var/www/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf

# Update uploads config
RUN echo "file_uploads = Onn" 
         "memory_limit = 1024Mn" 
         "upload_max_filesize = 512Mn" 
         "post_max_size = 512Mn" 
         "max_execution_time = 1200n" 
         > /usr/local/etc/php/conf.d/uploads.ini

# Enable headers module
RUN a2enmod rewrite headers

2

Answers


  1. Your mysql container does not have PHP installed.
    You need to run the command in your "app" container.

    Login or Signup to reply.
  2. The mysql image only contains the database. The entrypoint: setting says "run this command instead of what the container would have normally run, ignoring even its default setup". Since you’ve attached the entrypoint: to the database:, you try to run php artisan migrate instead of running MySQL, and you run it in a database-only image.

    The migration step needs to be attached to your application container, not the database container. I tend to write this as an entrypoint wrapper script, a script compiled into the image that runs as the image’s default ENTRYPOINT but that accepts a normal CMD as the actual main container process. The simplest form of this would look like

    #!/bin/sh
    # entrypoint.sh
    
    # run migrations
    php artisan migrate
    
    # run the main container `CMD` (or an execution-time override)
    exec "$@"
    

    The one complication here is that setting ENTRYPOINT in a Dockerfile also resets the CMD, and the php:apache images come with a default CMD. If you look at the Docker Hub php image page and then click through to the "Dockerfile links" page, you can find the official Dockerfile for php:8.0-apache. If you look at the end of that file, it has both an ENTRYPOINT and a CMD, so you need to replicate both of these in your setup.

    #!/bin/sh
    # entrypoint.sh
    
    ...
    
    # run the main container CMD, via the original ENTRYPOINT
    exec docker-php-entrypoint "$@"
    #    ^^^^^^^^^^^^^^^^^^^^^
    #    this is the base image's ENTRYPOINT
    
    # Dockerfile
    
    ...
    
    WORKDIR /var/www
    
    # copy the application source and supporting scripts into the image
    COPY ./ ./
    
    # set the entrypoint to our wrapper script, and repeat the base
    # image's command
    ENTRYPOINT ["./entrypoint.sh"]
    CMD ["apache2-foreground"]
    #   ^^^^^^^^^^^^^^^^^^^^^^
    #   this is the base image's CMD
    

    Now in your Compose setup, you don’t need to set a command: or entrypoint: for any of these containers, or mount the application code into the container; all of these details are already set in the image.

    version: "3.8"
    services:
        app:
            build: .
            depends_on:
                - mysql
            ports:
                - 8001:80
            # no working_dir: or volumes:
        mysql:
            image: mysql:latest
            volumes:
                - dbdata:/var/lib/mysql
            environment:
                MYSQL_DATABASE: ${DB_DATABASE}
                MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
                MYSQL_PASSWORD: ${DB_PASSWORD}
            ports:
                - 3306:3306
            # no entrypoint:
    volumes:
        dbdata:
            # empty
    # no need for top-level networks: in most applications
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search