美文网首页我爱编程
Laravel + Docker Part 1 — setup

Laravel + Docker Part 1 — setup

作者: c8ac4dad76db | 来源:发表于2018-07-24 19:56 被阅读28次

第一部分阐述如何通过 Docker 在本地运行 Laravel 应用。第二部分将完整地展示如何在生产中运行同样的应用。

本文的目标是创建一个可以复用的开发环境。快速,并且不依赖本地计算机的任何全局安装(除了 Docker 本身)。

所以,我们来实现以下目标:

  • 没有 Mamp或类似的程序
  • 没有 Vagrant或类似的VM设置
  • 没有 全局安装的PHP
  • 没有 全局安装的Composer

获取最新的Laravel

使用 curl 来从 Github 获取最新的 Laravel 版本,但是也可以以你喜欢的方式轻松获取源码——可以使用 git clone ,如果这样做的话,别忘了删除 .git 目录。

我们没有遵循设置 Laravel 的官方指南,因为我们不希望在我们的开发机器上全局安装 PHP/Composer 的麻烦

curl -L https://github.com/laravel/laravel/archive/v5.6.12.tar.gz | tar xz 

这将创建一个名为的目录 laravel-5.6.12 ——您应该将其重命名为您想要的项目。例如 mv laravel-5.6.12 my-site 然后 cd 进入它。

安装依赖

我们需要运行 composer install 来获取组成 Laravel 的所有库——我们可以从 docker hub 获取composer/composer 镜像来实现。

我们通过以下命令来创建一个用完即弃的容器:

docker run --rm -v $(pwd):/app composer/composer install

注意:

  • 我们使用 -rm 标识来确保安装后不会停留
  • -v $(pwd):/app 将宿主机上的当前目录挂载到容器的 /app 目录——这是运行在容器内的 composer 期望找到的 composer.json 位置。
  • -v $(pwd):/app 也确保了由 composer 在容器内部创建的文件夹在宿主机也能看得见。

创建docker-compose.yml

我们使用两个单独的文件来定义环境如何运行。一个用于开发,另一个用于生产。现在 docker-compose 支持使用多个输入文件(input files),允许覆盖特定的键——但是由于它合并数组的方式,并不适合我们的特定用例,我们只能在两个文件中忍受一些重复。

无论如何,我们都需要创建文件 docker-compose.yml 。它的开头是这样的:

version: '3'
services:
   ... our services will go here

PHP-FPM

这将处理在应用中的执行代码,我们使用此服务来执行任意的 php 脚本,例如运行 Laravel 附带的 CLI 工具 artisan

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

注意:

  • 我们将使用单独的 app.dockerfile 来构建我们的镜像,因为我们想要精确控制 PHP 正在使用的模块。
  • 我们将工作目录设置为 /var/www —— 应用程序代码将在容器内的位置。
  • 我们使用单个卷定义 ./:/var/www 将主机上当前目录中的所有内容挂载到 /var/www 容器中。这将允许我们对源代码进行更改,并将它们立即反映在正在运行的应用程序中。这将使您的应用程序在浏览器中感觉迟钝 - 几百毫秒滞后(特别是在OSX上),但不要担心——在第2部分,当我们转换到生产设置时,速度问题将不再存在。
  • 环境变量 DB_PORTDB_HOST 在此处设置相匹配了,我们稍后会创建数据库容器。

现在我们需要创建 app.dockerfile 我们在 build 上面的设置中引用的内容。

app.dockerfile

FROM php:7.2-fpm

RUN apt-get update && apt-get install -y libmcrypt-dev \
    mysql-client libmagickwand-dev --no-install-recommends \
    && pecl install imagick \
    && docker-php-ext-enable imagick \
    && docker-php-ext-install mcrypt pdo_mysql

注意:

  • 这里使用 php:7.2-fpm ,当然,也可以选择其他版本。
  • 接下来是典型的 Laravel CRUD 应用所需的基本知识

Nginx

接下来,我们需要配置处理静态文件的 Web 服务器,以及需要由 Laravel 应用处理的请求传递。我们将遵循与之前相同的模式,这次命名服务 web 及其随附文件 web.dockerfile

docker-compose.yml

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

注意:

  • 我们 volumes_from 在这里使用它来重用我们在上面的 PHP-FPM 服务中定义的内容。这意味着这个 Nginx 容器将继承该 /var/www 目录(该目录又安装到我们的开发机器上)。
  • 我们 8080 将主机上的端口映射到80容器中。这样我们就可以 0.0.0.0:8080 在开发过程中访问,而不需要乱用主机名。

web.dockerfile

FROM nginx:1.15

ADD -v nginx.conf:/etc/nginx/nginx.conf

nginx.conf

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;
    }
}

注意:

  • 第12行处理请求 app:9000 ,这是有效的,因为 docker-compose 会自动链接我们的服务,允许它们通过简单的主机相互 talk
  • 其余的只是非常基本的nginx配置 - 它没有以任何方式调整性能或安全——我们将在另一篇文章中处理这些!

MySQL

接下来,我们将配置数据库,但我们需要处理这个与以前的服务略有不同。使用 PHP-FPM 和 Nginx ,我们希望可以在容器内访问本地目录中的文件,以帮助加快开发过程。但是数据库不是这种情况相反,我们希望容器中创建的文件能够持久存在,从而允许我们在不丢失数据的情况下停止并重新启动服务。这也可以通过卷来实现,只是这次不需要它与我们的主机文件同步。

docker-compose.yml

version: '3'
services:

  database:
    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:

注意:

  • 第16行创建了一个卷 dbdata ,最后的冒号 : 是故意的,不需要担心。
  • 第7行引用了该卷,也就是说从 dbdata 卷加载 /var/lib/mysql 目录。
  • 第9~12行设置了MySQL的环境
  • 第13行,我们 33061 在主机上创建了一个添加端口映射到 3306 容器内的常规。这样做只是为了让外部工具在开发过程中更容易访问数据库——在生产设置中不需要它。

docker-compose.yml

version: '3'
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 Database
  database:
    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:

启动服务

如果跟着我们的步骤做下来,会有如下文件:

  • docker-compose.yml
  • app.dockerfile
  • web.dockerfile
  • nginx.conf

一旦完成所有这些操作,您就可以继续执行以下命令,该命令将启动所有 3 个服务。

docker-compose up

准备Laravel应用程序

环境配置文件

cp .env.example .env

应用密钥和优化

接下来,我们需要设置应用程序密钥并运行optimize命令。两者都由 artisan 处理,但因为我们有 PHP 和整个 Laravel 应用程序在容器内运行,我们不能像往常一样在我们的本地机器上运行 php artisan key:generate ——我们需要直接将这些命令发送到容器中。

幸运的是,docker-compose 有一个非常好的抽象来处理这个,所需的两个命令看起来像:

docker-compose exec app php artisan key:generate
docker-compose exec app php artisan optimize
image.png

你需要在任何时候使用这种模式 artisan —— 记住使用 docker 的目的是避免在本地机器上安装 PHP 版本的麻烦,这就是我们如何解决它 - 通过将命令发送到容器中,而不是直接运行它们。

您将在Laravel项目中经常运行的其他一些命令:

docker-compose exec app php artisan migrate --seed
docker-compose exec app php artisan make:controller MyController

提示:创建一个别名,这样 phpd 就不需要输入完整的命令,例如: phpd artisan migrate --seed

一旦你执行了前面提到的两个命令(artisan key:generateartisan optimize),应用程序现在就可以使用了 - 继续在浏览器中点击http://0.0.0.0:8080,你就会看到这个可爱的屏幕。

image.png

部署成功!

修改设置到生产环境

目前已经有一些博客涉及 Laravel 这样的开发环境,但到目前为止我还没有发现如何完成下一个重要步骤 —— 采用这种环境并为生产使用做好准备。我期待很快分享下一篇文章。

资源:

喜欢这个?如果你这样做,并且你发现自己在做任何前端工作,也许你会喜欢我在 https://egghead.io/instructors/shane-osbourn 上的一些课程,很多都是免费的,我会报道 Vanilla JS,Typescript ,RxJS 等。

相关文章

网友评论

    本文标题:Laravel + Docker Part 1 — setup

    本文链接:https://www.haomeiwen.com/subject/lydsmftx.html