In this article we will use Docker to build a fast, lightweight, reproducible Laravel and Vue project development environment on the PC that does not rely on any development kit installed on the PC (all dependencies of the development environment are installed in the Docker build container). Vue was added only because some projects use Vue to separate front-end and back-end development in Laravel projects. The development environment requires the installation of a front-end toolset. Front-end and back-end development can also be divided into two projects, which is beyond the scope of this article.

So our goal is to:

  • Software like Mamp/Wamp is not installed locally
  • No virtual machine like Vagrant is used
  • The toolset required for PHP development is not installed globally on the local computer
  • The toolset required for front-end development is not installed globally on the local computer
  • Mysql and Nginx are not installed globally on the local computer

Before you start, you need to install a Docker client. There are detailed installation methods on Docker’s official website.

Step 1: Get the Laravel source package

You can also use Wget or Git Clone to get the latest source package for Laravel projects. You can use cURL to get the latest source package for Laravel projects.

Curl - L - O https://github.com/laravel/laravel/archive/v5.5.0.tar.gz / && tar - ZXVF v5.5.0. Tar. Gz / && rm v5.5.0 tar. GzCopy the code

Delete the laravel-5.5.0 project directory with curl. Delete the laravel-5.5.0 project directory with curl.

Step 2: Add docker-comedy.yml

Create the docker-comemage.yml file in your project.

The Compose project is Docker’s official open source project, which is responsible for the rapid choreography of Docker container clusters. We know that using a Dockerfile template file makes it easy for users to define a separate application container. Compose compose compose compose compose compose compose compose compose compose compose compose compose compose compose

The layout file begins as follows:

version: '2'
services:
   # our services will go here
Copy the code

In the choreography file, each container is called a service, and services defines all the services (containers) used in the entire application.

App services

The container for the APP service will execute the code in our project.

app:
  build:
    context: ./
    dockerfile: app.dockerfile
  working_dir: /var/www
  volumes:
    - ./:/var/www
  environment:
    - "DB_PORT=3306"
    - "DB_HOST=database"
Copy the code

Notes:

  • We use theapp.dockerfileThis image file is used to build our App container. In this image file, we will image the CONFIGURATION of the PHP module used in the project, and also install additional NPM to build the front-end code.
  • working_dir: /var/wwwSet the working directory to/var/wwwIn the container the project code will be placed/var/wwwDirectory below, including usedocker exec appThe orders were all executed by/var/wwwFor the current working directory.
  • volumesIs the setting of the mount path of the data volume in the container. Here we define only one data volume and attach the host project directory to the container/var/wwwSo that any changes we make to the project code on the local computer are immediately synchronized to the container and vice versa, and any changes made to the code in the container are immediately fed back to the project on the local computer.
  • environmentSet the environment variable name, which we did hereDB_PORTandDB_HOSTSo you don’t have to modify the project.envThe file contains the values of these two items, of course, any environment variables that you need to set separately in the development environment can be written here, and Laravel reads the configuration usedDotEnvIt checks if the system has a set of specified environment variables and does not read them again.envThe file.

Now we need to create the app.dockerfile file mentioned in the build section above.

The FROM PHP: 7.1.22 - FPM# Update packages
RUN apt-get update

# Install PHP and composer dependencies
RUN apt-get install -qq git curl libmcrypt-dev libjpeg-dev libpng-dev libfreetype6-dev libbz2-dev

# Clear out the local repository of retrieved package files
# RUN apt-get clean

# Install needed extensions
# Here you can install any other extension that you need during the test and deployment process
RUN apt-get clean; docker-php-ext-install pdo pdo_mysql mcrypt zip gd pcntl opcache bcmath


# Installs Composer to easily manage your PHP dependencies.
RUN curl --silent --show-error https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# Install Node
RUN apt-get update &&\
    apt-get install -y --no-install-recommends gnupg &&\
    curl -sL https://deb.nodesource.com/setup_10.x | bash - &&\
    apt-get update &&\
    apt-get install -y --no-install-recommends nodejs &&\
    npm config set registry https://registry.npm.taobao.org --global &&\
    npm install --global gulp-cli

CMD php-fpm
Copy the code

Notes:

  • I first put NPM and Composer in the APP container, because it is often necessary to execute them during development. If you publish to production, you usually build the project code using a separate Composer instead of putting it in the container that runs the application. One of the core ideas of the container is to keep it simple. This allows you to quickly add containers with the same role.

The Web service

Next, we need to configure a Web server, which we named Web in the choreographer file

web:
  build:
    context: ./
    dockerfile: web.dockerfile
  working_dir: /var/www
  volumes_from:
    - app
  ports:
    - 8080:80
Copy the code

Notes:

  • volumes_fromUsed for reuse inappThe path of the data volume defined in the service
  • throughportsMap port 8080 of the local computer to port 80 of the Web container, so that in the development environment we do not need to set the hosts file, directly through the IP plus port can access the service.

The Web server uses nginx, so we need to use an Nginx image file to build the container. Before this, we need to set the vhost used in the project on the basis of the nginx image, so we need a web.dockerfile, which is defined as follows:

The FROM nginx: 1.10 the ADD vhost. Conf/etc/nginx/conf. D/default. ConfCopy the code

According to the definition of the image file, we put the project in the vhost. Conf copy to the/etc/container nginx/conf. D/default. Conf, such basic nginx configuration is configured, vhost. The conf are defined as follows:

server {
    listen 80;
    index index.php index.html;
    root /var/www/public;

    location / {
        try_files $uri /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info; }}Copy the code

Notes:

  • Because it’s a development environment, we just do the simplest configuration and don’t worry about tuning.
  • fastcgi_pass app:9000;Nginx passes requests to PHP via FastCGIapp9000 ports for service,docker-composeContainer services defined in services are automatically wired together, and each service refers to the other using the service name.

The Mysql service

Next we will configure the Mysql service. Unlike the previous two services, in the phP-FPM and Nginx containers, we configure the files on the local computer to be synchronized to the container for the container to access. This allows us to quickly get feedback on the changes we make to the files during development to speed up our development process. In a database container, we want files created in the container to persist (by default, files created in the container will also be destroyed when the container is destroyed). We can do this with the Docker data volume, but this time we don’t have to attach files from the local computer to the data volume. The Docker client manages the specific location of the created data volume on the local computer.

Here are the Settings for the Database service in the choreographer file


version: '2'Services: database: image: mysql:5.7 volumes: -dbdata :/var/lib/mysql environment: -"MYSQL_DATABASE=homestead"
      - "MYSQL_USER=homestead"
      - "MYSQL_PASSWORD=secret"
      - "MYSQL_ROOT_PASSWORD=secret"
    ports:
        - "33061:3306"

volumes:
  dbdata:
Copy the code

Notes:

  • At the bottom of the file we passvolumesThe command creates a file nameddbdata(the colon after dbdata is written intentionally, this is a syntactic limitation of YML files, so don’t worry too much)
  • After defining the data volume, above we use<name>:<dir>The format that notifies Docker willdbdataThe data volume is attached to the container/var/lib/mysqlIn the catalogue
  • environmentsSet the four necessary parameters for the docker image of Mysql.
  • portsIn port mapping, we map port 33061 of the local computer to port 3306 of the container, so that we can connect to Mysql in docker through the database tool on the computer.

Orchestrate all the services together

Below is the complete docker-comemage. yml file. By orchestrating the file we associate the three application containers together to form the server side of the project

version: '2'
services:

  # The Application
  app:
    build:
      context: ./
      dockerfile: app.dockerfile
    working_dir: /var/www
    volumes:
      - ./:/var/www
    environment:
      - "DB_PORT=3306"
      - "DB_HOST=database"

  # The Web Server
  web:
    build:
      context: ./
      dockerfile: web.dockerfile
    working_dir: /var/www
    volumes_from:
      - app
    ports:
      - 8080:80

  # The DatabaseDatabase: image: mysql:5.6 Volumes: -dbdata :/var/lib/mysql environment: -"MYSQL_DATABASE=homestead"
      - "MYSQL_USER=homestead"
      - "MYSQL_PASSWORD=secret"
      - "MYSQL_ROOT_PASSWORD=secret"
    ports:
        - "33061:3306"

volumes:
  dbdata:
Copy the code

Start the service

After following the above steps to configure the choreographer file and the specified Docker image file, we can start the service through the following command, which will start the three services defined in the above file.

docker-compose up -d 
Copy the code

At the first startup, docker client will have to download the three images mentioned above and build the service, so the startup speed will be slow. After downloading the images and building the service is completed, the subsequent startup will be very fast.

Initialize the Laravel project

After starting the service, we can initialize the Laravel project. The steps are as described in the official documentation, but we need to perform them in the container of the started app service:

docker-compose exec app composer install
docker-compose execDocker-compose app NPM install // Docker-compose if the front-end project is includedexec app cp .env.example .env
docker-compose exec app php artisan key:generate
docker-compose exec app php artisan optimize
docker-compose exec app php artisan migrate --seed
docker-compose exec app php artisan make:controller MyController
Copy the code

Notes:

  • Docker-compose exec sends the command to the specified container for execution
  • App is a service defined in docker-comemage. yml, which is a container running PHP-fPM
  • PHP artisan Migrate isa command to be executed in a container

Nginx logs:

  • Docker ps finds the Container ID of the nginx service
  • Docker exec it < contianer id > /bin/bash Enter the nginx container
  • For the specific path to the nginx log, see vhost.conf in the project

After executing the above command, you can access the project at http://127.0.0.1:8080/.

In my dead simple gist has a set of reference file convenient classmates reference https://gist.github.com/kevinyan815/fa0760902d29f19a4213b4a16fe0501b

Gist files are a little bit older, but there are some new PHP modules and Nodes that have been added to the gist. Previously, Composer was placed in a separate container, but you should be smart enough to see that you have already changed the files based on your needs.

Make your own PHPDocker image