Where to put the php artisan migrate command
Asked Answered
S

5

35

Trying to deploy the laravel application on docker stack .What I am confused or not able to figure out is where can I run this php artisan migrate:fresh to generate the tables required in mysql.

The services and the task are running well

docker-compose.yml

version: '3.3'

networks:
  smstake: 
    ipam:
      config:
        - subnet: 10.0.10.0/24

services:

    db:
        image: mysql:5.7
        networks:
          - smstake
        ports:
          - "3306:3306"
        volumes:
          - db_data:/var/lib/mysql
        environment:
          MYSQL_ROOT_PASSWORD: password
          MYSQL_DATABASE: smstake
          MYSQL_USER: root
          MYSQL_PASSWORD: password
        deploy:
          mode: replicated
          placement:
            constraints:
              - node.role == manager
    app:

        image: smstake:latest          
        ports:
          - 8000:80
        networks:
          - smstake

        command: docker-compose exec app php artisan migrate --seed
        deploy:
          mode: replicated
          replicas: 1
          placement:
            constraints:
              - node.role == manager
volumes:
    db_data:

Here is the dockerfile with which the image is generated

FROM alpine

ENV \
  APP_DIR="/app" \
  APP_PORT="80"

# the "app" directory (relative to Dockerfile) containers your Laravel app...
COPY app/ $APP_DIR
# or we can make the volume in compose to say use this directory 

RUN apk update && \
    apk add curl \
    php7 \
    php7-opcache \
    php7-openssl \
    php7-pdo \
    php7-json \
    php7-phar \
    php7-dom \
    php7-curl \
    php7-mbstring \
    php7-tokenizer \
    php7-xml \
    php7-xmlwriter \
    php7-session \
    php7-ctype \
    php7-mysqli \
    php7-pdo \
    php7-pdo_mysql\
    && rm -rf /var/cache/apk/*

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

RUN cd $APP_DIR && composer install

WORKDIR $APP_DIR

RUN chmod -R 775 storage
RUN chmod -R 775 bootstrap

#CMD php artisan migrate:fresh
CMD php artisan serve --host=0.0.0.0 --port=$APP_PORT

Tried adding to the Dockerfile as is commented but didn't solve the problem

Tried adding on docker-compose as command: php artisan migrate:fresh too

Previously was doing this in jenkins to make it work Now dont want it via jenkins

docker-compose up -d --force-recreate --build 

#Running commands on already running service 
docker-compose exec -T app php artisan migrate:fresh --seed --force
Superficies answered 18/2, 2018 at 10:50 Comment(0)
S
21

To my opinion, automate migrate is not a good way when creating container. You can do this after container is up with this one line code manually;

docker exec your_container_name php artisan migrate
Senaidasenalda answered 7/3, 2021 at 12:15 Comment(0)
S
19

This is how I solved it .Created a bash script called run.sh and added the php artisan migrations commands followed by the php serve command.

run.sh

#!/bin/sh

cd /app  
php artisan migrate:fresh --seed
php artisan serve --host=0.0.0.0 --port=$APP_PORT

Added entrypoint to the Dockerfile removing the CMD in the end which will run the commands desired.

copy ./run.sh /tmp    
ENTRYPOINT ["/tmp/run.sh"]

Remove the command from the docker-compose.yml

Superficies answered 18/2, 2018 at 16:38 Comment(6)
This approach isn't working for me. I'm running into the exact same problem. It appears as though the database is not up and running when run.sh is actually ran. Any thoughts?Luu
I guess that the main caveat to this is that it's going to run the migrations every time you start the container. That might not be desired.Hall
@Luu may be you need to post your Docerfile or docker-compose or some more details so that we can we get more information and tackle your issue.Superficies
Same issue as CBaker. It's ok if the db volume already exists, but if you run it on a fresh build, mysql is not up and running.Onaonager
@Onaonager nowadays I am doing that from CI server(Jenkins) in the build or deploy pipelineSuperficies
same problem of @Luu any solutions on 2021?Ordonnance
L
0

Yes, special script. I try to build deploy and testing throw docker-compose, so i run migrations in script before starting supervisor in docker-service "jobs":

#!/bin/sh

cd /var/www
php artisan migrate --seed

/usr/bin/supervisord -n -c /etc/supervisord.conf

And piece from my deploy-docker-compose.yml:

services:
    nginx:
        depends_on:
            - phpfpm ## NOT START BEFORE PHPFPM

    phpfpm:
        depends_on: 
            - jobs ## NOT START BEFORE MIGRATION
    jobs:
        # ....

This schema is not started in production yet;

UPD1

i had to create simple laravel command wait_db_alive:

public function handle()
{
    $i = 1;
    $ret = 1;
    while($i <= 10){
        echo 'connecting to host:'.config('database.connections.'.config('database.default').'.host').' try '.$i.'..';
        try {
            DB::connection()->getPdo();
            echo 'ok'.PHP_EOL;
            $ret = 0;
            break;
        } catch (\Exception $e) {
            echo 'error:' . $e->getMessage() .PHP_EOL;
            sleep(1);
            $i++;
        }
    }
    return $ret;
}

and edit init.sh to

#!/bin/sh

php artisan wait_db_alive && php artisan migrate --seed && /usr/bin/supervisord -n -c /etc/supervisord.conf

so, log for jobs:

jobs_1      | connecting to host:db try 1..error:SQLSTATE[HY000] [2002] Connection refused
jobs_1      | connecting to host:db try 2..error:SQLSTATE[HY000] [2002] Connection refused
jobs_1      | connecting to host:db try 3..ok
jobs_1      | Nothing to migrate.
jobs_1      | Seeding: ServicesTableSeeder
...
jobs_1      | Database seeding completed successfully.
jobs_1      | 2020-11-22 05:33:43,653 CRIT Supervisor is running as root.

UPD2

In some cases we need to start container without .env-file, then better init.sh for this:

#!/bin/sh
php artisan wait_db_alive && php artisan migrate --seed 
/usr/bin/supervisord -n -c /etc/supervisord.conf
Linville answered 20/11, 2020 at 15:7 Comment(0)
R
0

One quick way is to create temporary route to run migration.

Route::get('/migrate', function () {
    \Artisan::call('migrate');
    return \Artisan::output();
});
Recognizor answered 21/9, 2022 at 5:24 Comment(0)
R
-5

To run all migrate you need to be inside your container, for that you need to run your containers with docker-compose up, here u need to be with terminal in the directory where your docker-compose.yml file is.

after that, and with the same place of docker-compose.yml file, run this command to be inside your container:

docker exec -it name_of_container bash

and when you will be inside your container, go to your shared app inside the container, I think here is the app so cd app.

after all of this run:

php artisan migrate
Retroaction answered 18/2, 2018 at 11:34 Comment(4)
you are absolutely correct but how do I implement that in docker-compose.yml or dockerfile as I am using the docker stack to run the services in docker swarm modeSuperficies
u can connect ur docker stack with ssh paramsRetroaction
like in docker swarm the app may be running in any nodes available right cant ssh to particular nodes and ssh that might not be the solutionsSuperficies
docker-compose exec app php artisan migrateHall

© 2022 - 2024 — McMap. All rights reserved.