将 Laravel 开发环境由 Homestead 迁移到 Laravel Sail ( Docker ) 完整详细教程

Laravel框架
756
0
0
2022-04-12
标签   Laravel环境

微软的 wsl2 随着 Windows10 20H1 版本一同发布了,跟 wsl1 相比,wsl2 拥有了完整的 Linux 内核。基于 wsl2 运行的 Docker 可以得到原生 Linux 下的体验。

附:比较wsl1和wsl2

我有一个基于 Dcat Admin 开发的管理后台,将开发环境迁移到 Laravel Sail( Docker ) 后,打开页面的速度快了很多倍,再也没有之前的卡顿感了(相信用过 Homestead 开发项目的小伙伴深有体会)。因虚拟机与宿主机之间羸弱的跨 OS 文件性能,导致 Homestead 中运行的项目在宿主机浏览器打开时,给人的感觉总是很卡。而且每次启动 Homestead 耗时也很长,每次 coding 前,光打开 Homestead 这个「重量级」开发环境,就让人头疼。然而使用 Laravel Sail 后,几秒钟就能启动 Docker 容器,马上就能投入开发。即使是在笔记本电脑上,Laravel Sail 也显得特别轻量,风扇不再像之前那样狂转了。是时候将我们的开发环境由「卡慢」的 Homestead 迁移到Docker下了。

注意:摆脱卡顿感的前提是项目代码放在linux子系统中,而不是放在宿主机上。IDE或编辑器通过网络位置来打开项目,后面我会介绍。教程《搭建 Laravel Sail 开发环境 - Windows》中将项目代码放在 /mnt/c/code/mnt/d/code 这样的宿主机目录中,我认为是不恰当的,因为wsl2是运行在虚拟机中的,所以 wsl2 跨 OS 文件系统的性能同样很差。将代码放到宿主机目录,你的项目运行速度跟 Homestead 中运行一样卡。

写作约定

我们将使用 $ 表示命令提示符,表示命令运行在 Ubuntu 子系统中,如:

$ echo "Hello Laravel!"

不过,我们有很多命令需要运行在宿主机的 Windows PowerShell 或者 cmd 中,我们约定使用 > 标记,如:

> echo "Hello,Windows"

Laravel China 的 Sail 环境搭建存在的问题

虽然Laravel China 发布的《搭建 Laravel Sail 开发环境 - Windows》中介绍了基于 Laravel Sail 的开发环境搭建,但教程是基于建立一个新项目的实践来进行。该教程是通过执行以下脚本来构建新项目的:

$ curl -s https://laravel.build/example-app | bash

但是执行该命令由于要预先构建一个「先导镜像」,再加上国内的网络问题,导致非常耗时而且非常容易安装失败。所以我自己在实践中总结出了一条可行的方法,现在分享给大家。

基础环境准备

基础环境要求主要有以下几点:

  • windows 操作系统版本要达到要求
  • 开启 wsl2
  • 安装实用工具 Windows Terminal 和 Visual Studio Code
  • 安装 Ubuntu 子系统
  • 安装 Docker Desktop 并让 Docker Desktop 基于 wsl2 来运行
  • 基础环境准备可以完全参照《搭建 Laravel Sail 开发环境 - Windows》来进行,我跟教程作者不同的是「六、创建测试项目 」及后面的部分,前面的部分都可以参照教程来进行。基础环境准备方面我们就简单的走一遍流程。

windows操作系统版本

  • 执行 winver 命令查看 Windows 版本,你的 Windows 版本不能低于 20H2 版本。

将 Laravel 开发环境由 Homestead 迁移到 Laravel Sail( Docker )

如果你的操作系统版本较低,可以使用 Windows 更新或者「微软易升」来升级你的操作系统。而且我测试过了 Windows10 家庭版也可以满足环境要求,不需要花钱升级到专业版。

启用wsl2

点击win10左下角的搜索按钮,输入「功能」,打开「 windows 功能」界面:

开启必要的windows功能

开启以下功能:「适用于 Linux 的 Windows 子系统」、「虚拟机平台」两项功能。等待电脑重启后,就安装好了。

开启必要的windows功能

注意: 如无必要,不要开启「Hyper-v」,Hyper-v 的保留端口经常会导致 Docker 容器启动失败,很多时候启动容器时提示端口被占用,但是运行netstat -ano | findstr xxx又找不到占用端口的进程,这种情况就是 Hyper-v 导致的。

安装实用工具

  • Windows 应用商店搜索安装 Windows Terminal;
  • 安装 Visual Studio Code,安装 VS Code 时,如果提示是否将 VS Code 加入系统环境变量,选择 「是」。
  • 这里就不再赘述

安装 Ubuntu 子系统

Windows 应用商店搜索 Ubuntu,选择安装 Ubuntu 或者 Ubuntu 20.04LTS,两者二选一即可:

将Laravel开发环境由Homestead迁移到Docker(基于Laravel Sail,win10 操作系统)

点击开始菜单 Ubuntu 图标,启动 Ubuntu,按照提示设置用户名、密码,同时请记住自己设置的用户名和密码。启动中如果遇到问题,请使用搜索引擎搜索,一般都有解决方案。

附: 使用 WSL2 出现“参考的对象类型不支持尝试的操作”解决办法:
  • 下载此软件:NoLsp
  • 如果无法访问,使用百度网盘下载:
  • 网盘地址:pan.baidu.com/share/init?surl=bVZ0...
  • 提取码: vjge
  • 管理员身份运行 CMD,cd 到 NoLsp.exe 存放的目录,然后执行命令:
NoLsp.exe C:\windows\system32\wsl.exe
  • 如果你是在安装 Ubuntu 子系统的过程中出现这个问题,没有正确进入设置 Ubuntu 账号密码的阶段,可以打开开始菜单,右键 Ubuntu 图标,点击更多 -> 应用设置,点击重置按钮,重置你的 Ubuntu,如果你的 Ubuntu 子系统内有重要数据,请记得备份:
  • 将 Laravel 开发环境由 Homestead 迁移到 Laravel Sail ( Docker ) 完整详细教程
解决方法出处: 关于使用WSL2出现“参考的对象类型不支持尝试的操作”的解决方法

打开 Windows Terminal( shell 工具选择 Powershell),将 wsl2 设为默认的 Linux 子系统环境:

> wsl --set-default-version 2

运行以下命令,查看相关应用运行的 wsl 版本:

 > wsl --list --verbose

运行结果如下:

将 Laravel 开发环境由 Homestead 迁移到 Laravel Sail ( Docker ) 完整详细教程

请确保你的 Ubuntu-20.04 是运行的 wsl 版本为 2,如果你的版本为1,请运行以下命令切换:

> wsl --set-version Ubuntu-20.04 2

安装 Docker Desktop

到 Docker 官网下载安装 Docker Desktop,安装完成后,打开 Docker,开启 WSL2 :

开启 WSL2

与 Ubuntu 进行整合:

与 Ubuntu 进行整合

如果没看到Ubuntu选项,查看博客文章《搭建 Laravel Sail 开发环境 - Windows,docker选项设置 没有 ‘ubuntu’选项》来解决。

接下来配置 Docker Hub 镜像加速,按下图打开 Docker Desktop 配置界面:

配置 Docker Hub 镜像加速

将镜像加速的配置粘贴到相应位置:

"registry-mirrors": ["https://mirror.baidubce.com","https://hub-mirror.c.163.com","https://docker.mirrors.ustc.edu.cn"],

如果需要阿里云的镜像加速地址,需要自己去注册一个阿里云账号,每个人的加速地址都不一样。

登录阿里云后点击控制台,按照下图指示找到镜像加速地址:

申请阿里云的镜像加速地址

申请阿里云的镜像加速地址

至此,基础的软件工具都安装配置好了,后面部分跟《搭建 Laravel Sail 开发环境 - Windows》有所不同。

在 Ubuntu 子系统中安装 PHP 基础运行环境

在使用 Laravel Sail 前,我们需要先通过 Composer 来安装它,所以需要基础的 PHP 运行环境。

在 Windows Terminal 中启动 Ubuntu

打开 Windows Terminal ,选择 Ubuntu-20.04 选项卡:

在 Windows Terminal 中启动 Ubuntu

Ubuntu 更换国内源加速

首先备份原来的源,在 Ubuntu 子系统中运行以下命令:

$ sudo cp /etc/apt/sources.list sources.list.bak

使用 vim 打开 sources.list 文件:

$ sudo vim /etc/apt/sources.list

将 sources.list 的文件内容全部替换为以下内容并保存:

deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse

deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse

deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse

deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse

deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse

deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse

添加PPA源

在 Ubuntu 子系统中运行以下命令:

$ sudo sh -c "echo 'deb http://ppa.launchpad.net/ondrej/php/ubuntu focal main'  > /etc/apt/sources.list.d/ppa_ondrej_php.list"

更新资源列表

在 Ubuntu 子系统中运行以下命令:

$ sudo apt update

如果产生以下错误:

W: GPG error: ppa.launchpad.net/ondrej/php/ubuntu focal InRelease: The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY 4F4EA0AAE5267A6C
E: The repository ‘ppa.launchpad.net/ondrej/php/ubuntu focal InRelease’ is not signed.
N: Updating from such a repository can’t be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.

GPG error

执行以下命令导入你的公钥即可( 4F4E...7A6C 这一串公钥要换成你自己屏幕上输出的那个):

$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4F4EA0AAE5267A6C

设置成功后,重新重新更新资源列表:

$ sudo apt update

安装php8.0

在 Ubuntu 子系统中运行以下命令:

$ sudo apt install -y php8.0-cli php8.0-dev php8.0-pgsql php8.0-sqlite3 php8.0-gd php8.0-curl php8.0-memcached php8.0-imap php8.0-mysql php8.0-mbstring php8.0-xml php8.0-zip php8.0-bcmath php8.0-soap php8.0-intl php8.0-readline php8.0-msgpack php8.0-igbinary php8.0-ldap php8.0-redis

需要安装 fpm 或者 swoole 扩展的,在后面加上 php8.0-swoolephp8.0-fpm即可。

安装php7.4

在 Ubuntu 子系统中运行以下命令:

$ sudo apt install -y php7.4-cli php7.4-dev php7.4-pgsql php7.4-sqlite3 php7.4-gd php7.4-curl php7.4-memcached php7.4-imap php7.4-mysql php7.4-mbstring php7.4-xml php7.4-zip php7.4-bcmath php7.4-soap php7.4-intl php7.4-readline php7.4-pcov php7.4-msgpack php7.4-igbinary php7.4-ldap php7.4-redis

需要其他版本的PHP请自行安装。

你会发现我们并没有安装 php-fpm ,因为我们要使用 Docker 来构建开发环境,现在的 PHP 环境只要能够在 CLI 运行环境下运行 Composer 就够了。当然,由于 WSL2 中的 Ubuntu 拥有完整的内核,你可以直接在 Ubuntu 子系统中安装 Nginx , php-fpm, Mysql, Redis等,包括 swoole 扩展, 可以直接基于 Ubuntu 子系统来构建开发环境。这里我们就不再赘述。

切换PHP版本

由于很多扩展目前还不支持 PHP8.0,所以我们也同时安装了 PHP7.4 版本。很多时候我们需要切换不同版本的 PHP,通过以下命令来切换 PHP 版本:

  1. 切换 cli 运行模式下默认的 PHP 版本
$ sudo update-alternatives --config php
  1. 输入对应PHP版本的数字,完成切换:
  2. 输入相对应PHP版本的数字
  3. 切换 phpize 版本:
$ sudo update-alternatives --config phpize
  1. 切换 php-config 版本
$ sudo update-alternatives --config php-config
  1. 确认现在的PHP版本:
$ php -v

安装 Composer

复制以下命令粘贴到 Ubuntu 子系统中执行,以安装 composer ,并将 composer 镜像配置为阿里云镜像:

sudo sh -c "curl -so /usr/bin/composer https://mirrors.aliyun.com/composer/composer.phar && chmod a+x /usr/bin/composer" \
&& composer --version \
&& composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ \
&& composer config -g -l | grep repositories.packagist.org.url

如果控制窗口显示出了 Composer 版本和镜像源地址,说明安装成功了:

将 Laravel 开发环境由 Homestead 迁移到 Laravel Sail ( Docker ) 完整详细教程

至此,我们的PHP基础环境就安装好了。

开始安装 Laravel Sail

创建项目目录

进入你的 Ubuntu 子系统的家目录:

$ cd ~
注意: 这里是进入 Ubuntu 子系统的家目录,而不是Windows10的。

创建一个 projects 目录,用于存放项目代码:

$ mkdir projects

用 VS Code 打开家目录,VS Code 需要被加入到 Windows 的系统环境变量中:

$ code .
这里要注意,由于 WSL2 跨OS的文件性能很差,会导致项目运行速度很慢,所以我们的项目目录是存放在 Ubuntu 子系统中的家目录, 而不是 windows10 的家目录。后面调用code .命令是为了用 VS Code 打开我们的projects目录,以获取projects目录的网络位置路径,方便我们使用诸如 phpStorm 这样的 IDE 打开项目。

在 VS Code 界面,右键projects目录,选择Reveal in Explorer,也就是在 Windows文件管理器 中打开目录:

用VS Code打开projects目录

windows资源管理器中,右键projects目录,选择固定到快速访问发送到 -> 桌面快捷方式,便于以后打开项目目录。

创建projects目录的快捷访问

你也可以直接打开 「Windows 文件资源管理器」,在地址栏输入 \\wsl$ 打开,一级一级找到你的项目存放目录。

所以,即使我们的项目存放在 Ubuntu 子系统中,项目目录也是可以通过网络位置访问的,我第一次按照社区官方教程搭建 Laravel Sail 开发环境时,也是将项目存放在/mnt/c/code目录下,这就产生了跨OS的文件系统性能问题,项目的运行速度并没有令我满意。我也是在无意间在 Windows Terminal 中使用code命令打开 Ubuntu 子系统中的家目录时,才发现了可以通过网络位置打开项目目录。

将项目存放目录添加到 Windows Denfender 的白名单中

接下来,为了防止 Windows Defender 因安全原因,可能会阻止 IDE 扫描项目目录,所以我们将 projects目录加入 Windows Defender 的白名单中。

Windows资源管理器中打开projects目录,复制projects目录的路径:

复制projects目录的地址

打开Windows 安全中心, 按下图所示,打开病毒和威胁防护设置界面:

微信和防护设置

点击“添加或删除排除项”,点击“添加排除项”按钮,选择“文件夹”,将刚刚复制的projects目录的路径添加到排除项中,同时,也可以将你的IDE进程也添加到排除项中(点击“添加排除项”按钮,选择“进程”):

添加projects目录的路径到排除项

拉取项目源码

回到 Windows Terminal 界面,命令行工具选择 Ubuntu,进入项目存放目录:

$ cd /home/myhui/projects

假设我们现在有一个项目,叫做 kkyn_dcat_admin,拉取你的项目源代码(或者创建新的项目):

$ git clone git@gitee.com:kkyn_dcat_admin.git

如果是全新的项目,你也可以使用 composer 创建一个新的 Laravel 项目:

$ composer create-project laravel/laravel Example --prefer-dist "8.*"
这里说明一下,如果你使用ssh协议拉取项目源码,由于 Ubuntu 子系统跟 Windows10 宿主系统是隔离的,所以你需要将 windows 10 的 SSH Key 拷贝到 Ubuntu 子系统中(注意不要完全复制粘贴命令,ASUSmyhui要改成你自己的:smiley:。):
$ cp /mnt/c/Users/ASUS/.ssh/id_rsa* /home/myhui/.ssh/
如果你还没有SSH KEY,可以用 Git Bash 重新生成 SSH Key,并将生成的公钥添加你的github或者gieee信任列表中。打开 Git Bash,运行以下命令:
ssh-keygen -t rsa -C "your_email@example.com
具体步骤 不再赘述。

安装Laravel Sail

使用 IDE 或者编辑器打开项目,这里我们使用 PhpStorm:

打开项目

编辑composer.json文件,添加"laravel/sail": "^1.8" 开发依赖:

将 Laravel 开发环境由 Homestead 迁移到 Laravel Sail ( Docker ) 完整详细教程

或者使用 composer require laravel/sail --dev安装最新版 laravel-sail.

小提示:用 PhpStorm 通过网络位置打开位于 Ubuntu 子系统内的项目时,点击 PhpStorm 下面的 Terminal 工具,PhpStorm 会自动进入 Ubuntu 子系统的 shell 环境,所以不用傻傻的 Windows Terminal 与 PhpStorm 来回切换了。
将 Laravel 开发环境由 Homestead 迁移到 Laravel Sail ( Docker ) 完整详细教程

回到 Windows Terminal 界面, 打开 Ubuntu 选项卡,进入你的项目目录:

$ cd ~/projects/kkyn_dcat_admin

查看你的当前用户在 Ubuntu 中的 UID:

$ id myhui

先保存运行结果,稍后会用到:

uid=1000(myhui) gid=1000(myhui) groups=1000(myhui),0(root),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),117(netdev),1001(docker)

发布.env文件

$ cp .env.example .env

用IDE编辑.env文件,配置你的 APP_SERVICE、WWWUSER、WWWGROUP、mysql、redis 选项,其中 APP_SERVICE 的目的是为了 sail 与容器交互,WWWUSER、WWWGROUP 可以保证使用诸如sail artisan make:migration xxx这种命令生成的文件所属的用户与用户组与你的当前用户相同,避免文件操作的权限问题:

# 镜像服务名称
APP_SERVICE=kkadmin.test
# 上面生成的UID
WWWUSER=1000
# 上面生成的用户组名称
WWWGROUP=1000

# mysql
DB_CONNECTION=mysql
DB_HOST=mysql
FORWARD_DB_PORT=33060 #从容器映射到外部的端口,管理工具可通过此端口管理数据库
DB_PORT=3306
DB_DATABASE=kkyn
DB_USERNAME=root
DB_PASSWORD=password

# redis
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379
REDIS_CLIENT=phpredis

执行命令安装依赖:

$ composer install
注意:我们安装在 Ubuntu 子系统中的php环境主要用来安装依赖,如果你不想使用Docker来做开发环境,请自行在 Ubuntu 子系统中安装诸如mysql、redis等的其他软件。

发布 docker-compose.yml 文件

docker-compose 用于编排容器,运行以下命令发布配置文件:

$ php artisan sail:install --with=mysql,redis

with选项可选的值有 mysql, pgsql, mariadb, redis, memcached, meilisearch, mailhog, selenium。自己根据情况选择。如果运行php artisan sail:install命令不带--with选项,会出现一个选择框,选择需要一同参与编排的镜像列表。

发布 Dockerfile 以便定制

注意:如果你能解决* 科 * 学 * 上 * 网问题,就不要再进行定制了,最近使用定制的 Dockerfile 构建镜像时总是出现包依赖问题,最终导致镜像构建失败,我暂时没有找到解决方案。It is recommended to use the TUN model ladder. 当然,如果没有条件,你也可以继续按照教程进行,如果出现错误请在评论区留言。
提示:如果你无法解决网络问题,或者多次尝试后镜像构建总是失败,可以使用我已经构建好的 Docker 镜像,我已经共享到了百度网盘。请参照文章《使用构建好的 Docker 镜像来搭建 Laravel Sail 开发环境,解决 Laravel Sail 镜像构建失败的问题》

由于国内的网络问题,我们需要对 Dockerfile 进行定制,以获得更快的构建速度。运行下面的命令,发布 Dockerfile 文件:

$ php artisan sail:publish

命令运行完成后,你可以看到项目目录中,多了一个docker目录。

定制 Dockerfile

用 IDE 或编辑器打开 kkyn_dcat_admin/docker/7.4/Dockerfile文件, 按照以下步骤进行定制。这里我们定制的是 php7.4 镜像,需要 PHP8 运行环境的小伙伴可以选择定制 docker/8.0 目录下的 Dockerfile

  1. kkyn_dcat_admin/docker/7.4目录下,创建一个sources.list文件,将以下内容粘贴进去:
特别提醒:由于 Laravel Sail 的默认依赖 Ubuntu 版本更新到了 21.04,所以你的 sources.list 文件的加速地址也要用 21.04 的,自己根据实际情况选择合适的加速镜像。

以下是 Ubuntu 20.04 的加速镜像地址:

deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse

附上 Ubuntu 21.04(hirsute) 的加速镜像地址:

deb http://mirrors.aliyun.com/ubuntu hirsute main restricted
deb http://mirrors.aliyun.com/ubuntu hirsute-updates main restricted
deb http://mirrors.aliyun.com/ubuntu hirsute universe
deb http://mirrors.aliyun.com/ubuntu hirsute-updates universe
deb http://mirrors.aliyun.com/ubuntu hirsute multiverse
deb http://mirrors.aliyun.com/ubuntu hirsute-updates multiverse
deb http://mirrors.aliyun.com/ubuntu hirsute-backports main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu hirsute-security main restricted
deb http://cn.archive.ubuntu.com/ubuntu hirsute-security universe
deb http://cn.archive.ubuntu.com/ubuntu hirsute-security multiverse
  1. 配置 Ubuntu 国内镜像
  2. 回到Dockerfile文件,在 RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone这句代码下面,加入以下代码:
ADD sources.list /etc/apt/
  1. Ubuntu PPA 加速
特别提示: 现在不做这一步了,ustc这个加速镜像已经无法使用。速度慢的话多等几分钟就行。实在不行就 * 科 * 学 * 地 * 上 * 网 * ,命令行使用 TUN 模式的 proxy 就可以了。

Dockerfile文件中,搜索:

http://ppa.launchpad.net

将其替换为:

https://launchpad.proxy.ustclug.org
  1. 安装Composer

Dockerfile文件中,搜索下面这行代码:

    && php -r "readfile('http://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer \

将其替换为以下代码:

&& curl -so /usr/bin/composer https://mirrors.aliyun.com/composer/composer.phar \
&& chmod a+x /usr/bin/composer \
&& composer --version \
&& composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ \

完整的 Dockerfile 如下:

FROM ubuntu:20.04

LABEL maintainer="Taylor Otwell"

ARG WWWGROUP

WORKDIR /var/www/html

ENV DEBIAN_FRONTEND noninteractive
ENV TZ=UTC

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

ADD sources.list /etc/apt/

RUN apt-get update
    && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python2
    && mkdir -p ~/.gnupg
    && chmod 600 ~/.gnupg
    && echo "disable-ipv6" >> ~/.gnupg/dirmngr.conf
    && apt-key adv --homedir ~/.gnupg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys E5267A6C
    && apt-key adv --homedir ~/.gnupg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C300EE8C
    && echo "deb https://launchpad.proxy.ustclug.org/ondrej/php/ubuntu focal main" > /etc/apt/sources.list.d/ppa_ondrej_php.list
    && apt-get update
    && apt-get install -y php7.4-cli php7.4-dev
       php7.4-pgsql php7.4-sqlite3 php7.4-gd
       php7.4-curl php7.4-memcached
       php7.4-imap php7.4-mysql php7.4-mbstring
       php7.4-xml php7.4-zip php7.4-bcmath php7.4-soap
       php7.4-intl php7.4-readline php7.4-pcov
       php7.4-msgpack php7.4-igbinary php7.4-ldap
       php7.4-redis
    && curl -so /usr/bin/composer https://mirrors.aliyun.com/composer/composer.phar
    && chmod a+x /usr/bin/composer
    && composer --version
    && composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
    && curl -sL https://deb.nodesource.com/setup_15.x | bash -
    && apt-get install -y nodejs
    && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list
    && apt-get update
    && apt-get install -y yarn&& apt-get install -y mysql-client
    && apt-get install -y postgresql-client
    && apt-get -y autoremove
    && apt-get clean
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

RUN setcap "cap_net_bind_service=+ep" /usr/bin/php7.4

RUN groupadd --force -g $WWWGROUP sail
RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail

COPY start-container /usr/local/bin/start-container
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY php.ini /etc/php/7.4/cli/conf.d/99-sail.ini
RUN chmod +x /usr/local/bin/start-container

EXPOSE 8000

ENTRYPOINT ["start-container"]
注意: 最新版的 Laravel Sail 已经将基础镜像更新到 Ubuntu:21.04,注意核对自己的 sources.list 加速地址配置是否匹配。

定制docker-compose.yml文件

将 Laravel 开发环境由 Homestead 迁移到 Laravel Sail ( Docker ) 完整详细教程

其他可定制项包括应用的端口、MySQL的端口等等,根据自己的需求定制。不熟悉 Docker 的朋友请自行学习。

构建镜像并启动容器

使用Windows Terminal,打开 Ubuntu 标签页,通过 Ubuntu 进入你的项目目录~/projects/kkyn_dcat_admin,执行以下命令:

$ ./vendor/bin/sail up

看到以下界面,说明已经启动成功了

将 Laravel 开发环境由 Homestead 迁移到 Laravel Sail ( Docker ) 完整详细教程

通过 Docker Desktop 界面可以看到容器的运行情况:

将 Laravel 开发环境由 Homestead 迁移到 Laravel Sail ( Docker ) 完整详细教程

生成KEY:

$ ./vendor/bin/sail artisan key:generate

运行数据迁移:

$ ./vendor/bin/sail artisan migrate
注: 如果以上命令不生效,可以进入容器里面执行命令
进入容器:
$ docker exec -it kkyn_dcat_admin_kkadmin.test_1 /bin/bash
运行命令:
$ php artisan key:generate
$ php artisan migrate
如果你不知道自己的容器名叫什么,可以运行以下命令查看:
$ docker ps -a
见下图,复制NAMES下对应的容器名,当然,建议你花 1 个小时学一下 Docker:
将 Laravel 开发环境由 Homestead 迁移到 Laravel Sail ( Docker ) 完整详细教程

编辑 hosts 文件,配置开发用的域名(同时记得删除或注释掉 Homestead的域名解析配置):

# 注释掉 Homestead 的域名解析配置
#192.168.10.10 example.test
127.0.0.1 example.test

至此,整个Laravel Sail环境就搭建完成了,浏览器访问example.test:

将 Laravel 开发环境由 Homestead 迁移到 Laravel Sail ( Docker ) 完整详细教程

由于这种搭建方式不存在跨OS的文件性能问题,所以运行速度比 Homestead 快多了。

给 PhpStorm 配置 PHP CLI Interpreter

打开 Phpstorm,选择 File -> Settings -> PHP

注:我这是最新版的 PhpStorm ,老版本的 PhpStorm 位置略有不同。
  1. 配置所依赖的 PHP 版本
  2. 将 Laravel 开发环境由 Homestead 迁移到 Laravel Sail ( Docker ) 完整详细教程
  3. 配置 PHP CLI 接口
  4. 将 Laravel 开发环境由 Homestead 迁移到 Laravel Sail ( Docker ) 完整详细教程
  5. 将 Laravel 开发环境由 Homestead 迁移到 Laravel Sail ( Docker ) 完整详细教程

项目目录权限

由于 Ubuntu 子系统有自己的权限系统,很多时候与宿主机交互会遇到很多文件权限问题,所以建议将你的projects目录权限改为777:

$ sudo chmod -R 777 ~/projects/

数据库管理工具接入 MySQL

以 HeidiSQL 为例:

将 Laravel 开发环境由 Homestead 迁移到 Laravel Sail ( Docker ) 完整详细教程

停止容器服务

  1. 通过 Docker Desktop 停止:
  2. 通过 Docker Desktop 停止
  3. 通过 Laravel Sail 停止:
  4. 进入 Ubuntu 子系统,在项目目录下(本教程中的目录为~/projects/kkyn_dcat_admin)运行以下命令:
$ ./vendor/bin/sail stop
附:还可以使用./vendor/bin/sail down来停止当前容器服务,这个命令的解释为:Stop and remove resources,会 停止并删除资源, 也就是会把创建好的容器删除了,运行./vendor/bin/sail up时会重新构建一个容器,不过速度也很快。但是我还是推荐使用stop命令,感觉stop命令更适合Stop services。所有命令的用法请运行./vendor/bin/sail -h查看。
  1. Ctrl + C直接停止
  2. 展示容器服务运行状态的 Windows Terminal 里面直接Ctrl + C就能停止所有容器。

启动容器

  1. 通过 Docker Desktop 启动:
  2. 通过 Docker Desktop 启动
  3. 通过Laravel Sail 启动:
  4. 打开 Windows Ternimal, 切换到 Ubuntu 选项卡,进入项目目录(本教程中的目录为~/projects/kkyn_dcat_admin),运行以下命令:
$ ./vendor/bin/sail up
  1. 如果你想在后台执行该服务,加上-d参数:
$ ./vendor/bin/sail up -d
注:还有一个启动容器服务的 sail 命令:./vendor/bin/sail start,但是运行该命令后会删除掉所有的容器,然后提示ERROR: No containers to start,可能还有Bug,所以不推荐使用。
  1. 通过 docker-compose 启动:
  2. 同样的步骤,打开 Windows Ternimal, 切换到 Ubuntu 选项卡,进入项目目录,执行命令:
$ docker-compose up
  1. 如果你想在后台执行该服务,加上-d参数:
$ docker-compose up -d

配置 Bash 别名

为了避免频繁的使用./vendor/bin/sail xxx这种形式的命令,而是直接使用sail xxx这种简写形式,在 Ubuntu 子系统内,复制并运行以下命令:

echo 'alias sail="bash vendor/bin/sail"' >> ~/.bashrc && source ~/.bashrc