Laravel-Docker during development
google.com

Laravel-Docker during development


Introduction

In this article i'm going to show you how to use docker-compose to build multiple services to setup a Laravel PHP project on your local machine.

And since we use docker so you don't need to install any tools on your machine except for docker to create liable application.

The Target setup

We need a server that handle incoming requests which then triggers the PHP interpreter to run our PHP code for these incoming requests, and setting all of that up on your local machine combined with MYSQL on MongoDB databases, that be quite annoying.

Now here's your target setup, which you wanna achieve in this article therefore. And this will be a setup which allows you to build a Laravel applications without installing anything on your host machine, except for Docker.

1- We have a some folder on your host machine that contain the source code of this Laravel application.

2- This source code folder will then exposed to one container The PHP interpreter which has PHP insalled inside of it.

3- Beside this PHP interpreter which you need to run your code, you also need that extra server and that's when you'll have a second container which has Nginx in it.

4- Now for storing data, you're going to add a MySQL database which of course your PHP interpreter in the end needs to be able to communicate with.

5- Besides these three application containers my setup also needs a couple of utility containers because it turns out that in Laravel application, there are three kind of tools, utilities, which you need composer, artisan, and npm.

Target Setup


1. Adding a Nginx Container

So let's get started writting some code here.

I'm going to start by adding docker-compose.yaml file then adding my first service configurations to be like that:

version: "3.8"
services:
    server:
        build:
            context:?.
            dockerfile:?dockerfiles/nginx.dockerfile
        ports:
            -?"8000:80"
        volumes:?
            -?./src:/var/www/html
            -?./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
        depends_on:
            -?php
            -?mysql

        

As you can see above, I have built my first service Nginx web server from a dockerfile which is like that:


FROM?nginx:stable-alpine

WORKDIR?/etc/nginx/conf.d

COPY?nginx/nginx.conf?.

RUN?mv?nginx.conf?default.conf

WORKDIR?/var/www/html

COPY?src?.
        

And also as you see above, I have copied Nginx conf file that you could get it from officail Nginx docker-hub image from here, then you are ready for the next service.


2. Adding a PHP Container

So let's now work on the PHP container

The PHP service will be relatively straight forward, i actually also use a custom dockerfile though, because there is no finished image which have everything i need.


version: "3.8"
services:
    server:
        build:
            context:?.
            dockerfile:?dockerfiles/nginx.dockerfile
        ports:
            -?"8000:80"
        volumes:?
            -?./src:/var/www/html
            -?./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
        depends_on:
            -?php        
            -?
            - mysql
    php:
       build:
            context:?.
            dockerfile:?dockerfiles/php.dockerfile
        volumes:
            -?./src:/var/www/html:delegated   
        

As you can see above, I have built my second service PHP interpreter from a dockerfile which is like that:


FROM?php:7.4-fpm

WORKDIR?/var/www/html

COPY?src?.

RUN?docker-php-ext-install?pdo?pdo_mysql

RUN?chown?-R?www-data:www-data?/var/www/html
        

Note: don't forget the fifth instruction layer that is a command to run in your php container in order to change user and group whos owner the source code directory to www-data and this is an important step in Laravel to prevent permession denied issue.

You could get the official PHP docker-hub image from here, then you are ready for the next service.


3. Adding a MySQL Container

It shouldn't come as a surprise that we also have an official docker-hup image for MySQL which you can use like PHP and Nginx.



version: "3.8"
services:
    server:
        build:
            context:?.
            dockerfile:?dockerfiles/nginx.dockerfile
        ports:
            -?"8000:80"
        volumes:?
            -?./src:/var/www/html
            -?./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
        depends_on:
            -?php

            -?
            - mysql
    php:
       build:
            context:?.
            dockerfile:?dockerfiles/php.dockerfile
       volumes:?
            -?./src:/var/www/html:delegated
    mysql:
       image:?mysql:5.7
       env_file:
            - ./env/mysql.env

                  

As you can see above, I have built my third service MySQL from the official docker-hub image and pass env_file to it.

The mysql service env_file will be like this below:


MYSQL_DATABASE=homestead
MYSQL_USER=homestead
MYSQL_PASSWORD=secret
MYSQL_ROOT_PASSWORD=secret
        

Note: you have to remember?these values in mysql env_file, because you'll use it in the Laravel .env file

Now you have a three application containers which you'll up and down, but you still have no any source code, so let's move on to the next step or next first utility service.


4. Adding a Composer Utility Container

Let's now ensure that i'm going to setup this container, which will now be a utility container, which will then not only be used inernally by Laravel, but which most importantly can be used by me to also setup a Laravel application in the fisrt place.


version: "3.8"
services:
    server:
        build:
            context:?.
            dockerfile:?dockerfiles/nginx.dockerfile
        ports:
            -?"8000:80"
        volumes:?
            -?./src:/var/www/html
            -?./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
        depends_on:
            -?php

            -?
            - mysql
    php:
        build:
            context:?.
            dockerfile:?dockerfiles/php.dockerfile
        volumes:?
            -?./src:/var/www/html:delegated
    mysql:        
    
        image:?mysql:5.7
        env_file:
            - ./env/mysql.env
    composer:
        build:
            context:?./dockerfiles
            dockerfile:?composer.dockerfile
        volumes:
            -?./src:/var/www/html

                            

As you can see above, I have built my fourth service Composer from a dockerfile which is like that:


FROM?composer:latest

WORKDIR?/var/www/html

ENTRYPOINT?[?"composer",?"--ignore-platform-reqs"?]
        

Note: i add "--ignore-platform-reqs" as an option for composer entrypoint command in order to ignore platform requirements warrnings.

Now you can use these four services to compose-up your Laravel application and your source code, but let me finish creating all services and then list all commands to up all services in the best way, so let's move on to the next utility service.


5. Adding a Artisan Utility Container

Let's continue with the artisan container, which we need to run certian level commands in Laravel project for example, to populate the database with some initial data.


version: "3.8"
services:
    server:
        build:
            context:?.
            dockerfile:?dockerfiles/nginx.dockerfile
        ports:
            -?"8000:80"
        volumes:?
            -?./src:/var/www/html
            -?./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
        depends_on:
            -?php

            -?
            - mysql
    php:
        build:
            context:?.
            dockerfile:?dockerfiles/php.dockerfile
        volumes:?
            -?./src:/var/www/html:delegated
    mysql:
        image:?mysql:5.7
        env_file:
            - ./env/mysql.env
    composer:
        build:
            context:?./dockerfiles
            dockerfile:?composer.dockerfile
        volumes:        
            -
            -?./src:/var/www/html
    artisan:
        build:
            context:?.
            dockerfile:?dockerfiles/php.dockerfile
        volumes:?
            -?./src:/var/www/html
            entrypoint:?["php",?"/var/www/html/artisan"]
        

As you can see above, I have built my fifth utility service Artisan from the same php dockerfile which used in building PHP service, and overwrite it by adding entrypoint instruction in my docker-compose.yaml file to run artisan file that will be exist in your source code.

Last service regarding to my target setup will be NPM, which used in laravel for frontend and UI staff. Let's se the updated yaml file.


6. Adding a NPM Utility Container

Npm is quite simple, here i'll use use the node image.


version: "3.8"
services:
    server:
        build:
            context:?.
            dockerfile:?dockerfiles/nginx.dockerfile
        ports:
            -?"8000:80"
        volumes:?
            -?./src:/var/www/html
            -?./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
        depends_on:
            -?php

            -?
            - mysql
    php:
        build:
            context:?.
            dockerfile:?dockerfiles/php.dockerfile
        volumes:?
            -?./src:/var/www/html:delegated
    mysql:
        image:?mysql
        env_file:
            - ./env/mysql.env
    composer:
        build:
            context:?./dockerfiles
            dockerfile:?composer.dockerfile
        volumes:
            -
            -?./src:/var/www/html
    artisan:
        build:
            context:?.
            dockerfile:?dockerfiles/php.dockerfile
        volumes:?
            -?./src:/var/www/html
            entrypoint:?["php",?"/var/www/html/artisan"]
    npm:
        image:?node
        working_dir:?/var/www/html
        entrypoint:?["npm"]
        volumes:
            -?./src:/var/www/html?
        


Now i have finished the instructions setup, then let list all commands tou have to run in the same order to up your Laravel project.

1. Generate the source code using composer utility service:

# docker-compose run --rm -d composer create-project laravel/laravel .        

2. Edit your .env file in laravel source code (section of connecting to DB):

DB_CONNECTION=mysql               
DB_HOST=mysql                    // name of mysql serviece ...
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead        

DB_PASSWORD=secret        

3. Run database migration using artisan utility service:

docker-compose run --rm -d artisan migrate        

4. Generate node_modules and UI staff using npm utility service:

docker-compose run --rm -d npm install        

5. Start your compose by up server which in turn will up other services because it depends on them:

docker-compose up --build -d server        

Note: you should see result like that in your terminal (and docker desktop windows users):

No alt text provided for this image
No alt text provided for this image

Then if you go to in your browser and in your localhost on port 8000 you will see Laravel project successfully run

No alt text provided for this image


In the end, this is my first article. I hope it helps you. If there are any comments, do not hesitate to send them to me.

Thank you ..




要查看或添加评论,请登录

社区洞察

其他会员也浏览了