自发布 《将 Laravel 开发环境由 Homestead 迁移到 Laravel Sail ( Docker ) 完整详细教程》 这篇文章以来,已经有 1900 多个阅读了,看来大家都在积极拥抱 Laravel Sail 开发环境,开始逐步淘汰 Homestead。
Laravel Sail 开发环境仅支持 Laravel8 及以上版本,很多老一点的项目是基于5 - 7版本的。对于这些项目,我们只要自己构建一个 PHP 运行容器接入 Laravel Sail 创建好的 MySql、 Redis等容器,然后写一个 shell 脚本(my-sail.sh)与容器交互,我们就将开发环境都统一成 Laravel Sail 了。
当然,即使是基于 laravel8 的新项目,你可能不愿意再次搭建和编排新的MySQL、Redis 容器,或者多个项目之间需要使用相同的 MySQL、Redis 容器,这篇文章都适合你。
对于有 Linux 基础和 Docker 基础的人来说,自己完全可以独立构建镜像并编排运行容器。但对于很多 Linux 和 Docker 知识不是很牢靠的开发者而言,写一篇简单易懂的入门接入教程还是很有必要的。让我们开始吧,假如我们现在有一个基于 Laravel7 开发的应用 Leona,我们将从拉取项目代码开始,一步一步接入已经通过 Laravel Sail 构建好的MySQL、Redis容器。
《记一次 hosts 文件配置错误导致应用卡顿的奇葩问题》
配置 .env 环境变量文件:
回到项目 IDE 界面,打开 Terminal ,创建 .env 环境配置文件:
cp .env.example .env
为了小白不犯错,放个截图:
参考以下的环境变量(.env)配置,配置你自己的 .env 文件:
APP_NAME=Leona
APP_ENV=local
APP_KEY=
APP_DEBUG=true
DOCKER_PORT=9233 #Docker容器映射出来的端口
APP_URL="http://leona.test:${DOCKER_PORT}" #应用地址
# Docker容器相关的环境变量
WWWUSER=1000 #运行id命令查看自己的 uid 和 gid
WWWGROUP=1000
MYSQL_CONTAINER_NAME=kkyn_dcat_admin_mysql_1 #需要接入的数据库容器的名称,这里要改成你自己的
DOCKER_NETWORK=kkyn_dcat_admin_sail #之前构建好的 Sail 服务的network,这里改成你自己的
DOCKER_CONTAINER_NAME=leona #当前应用的容器名称
# 数据库配置
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=leona
DB_USERNAME=root #为了避免不必要的麻烦,使用root账号
DB_PASSWORD=kkyn #root账号的密码与 Laravel-Sail 中 docker-compose.yml 中的 "MYSQL_ROOT_PASSWORD" 配置相同
# Redis配置
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379
REDIS_CLIENT=phpredis
注意: 为了我们新构建的容器接入之前已经构建好的 MySQL 与 Redis 容器,需要让新容器与之前构建好的 Sail 服务处于同一网络下,运行以下命令查看自己的 Docker 网络:
docker network ls
复制自己的网络名称,写到 .env 文件的 DOCKER_NETWORK
项:
同时为了能够在 MySQL 容器内自动创建所需的数据库,需要知道之前构建好的 MySQL 容器的名称,可以通过 Docker Desktop 查看自己的 MySQL 容器名称,并将容器名称配置给MYSQL_CONTAINER_NAME
环境变量:
写一个简易的 sail 脚本
为了方便我们构建容器并与容器交互,我们参照 Laravel Sail 的实现方式,写一个自己的简易 sail。
大家都知道,Laravel Sail 的核心就是./vendor/laravel/sail/bin/sail
文件,这是一个方便我们使用 Docker 的 shell 脚本文件,我们参考这个 shell 脚本文件。写一个简单的 my-sail.sh
文件,方便我们构建容器并与容器交互。
新建 my-sail.sh 文件
打开 PhpStorm,在项目目录(~/projects/leona
)下新建 my-sail.sh
文件,脚本内容我已经写好了,你只需要将以下内容复制粘贴进去:
#!/usr/bin/env bash
# 定义终端显示字体的颜色
WHITE='\033[0;37m'
NC='\033[0m'
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
# 将.env文件中的配置项导入当前脚本,相当于定义了与环境变量 key 同名的shell变量
# shellcheck source=.env
source .env
# 当前目录的路径
CURRENT_DIR="$(pwd)"
# 设置shell脚本运行的用户名与用户组环境变量,如果环境变量文件内没有配置,则使用运行脚本的当前用户属性
export WWWUSER=${WWWUSER:-$UID}
export WWWGROUP=${WWWGROUP:-$(id -g)}
# 创建数据库
create_database(){echo "正在创建数据库..."
docker exec -i "${MYSQL_CONTAINER_NAME}" /bin/bash <<EOF
mysql -u${DB_USERNAME} -p${DB_PASSWORD}
CREATE DATABASE ${DB_DATABASE} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
exit
EOFprintf "${GREEN}%s\n" "数据库${DB_DATABASE}创建成功"
}
# 创建容器函数
run_container(){echo "正在安装依赖..."
composer installecho "生成APP_KEY..."
php artisan key:generate
printf "${NC} %s\n" "正在创建容器: ${DOCKER_CONTAINER_NAME} ..."
docker run --name "${DOCKER_CONTAINER_NAME}" \
-v "${CURRENT_DIR}":/var/www/html \
-p "${DOCKER_PORT}":80 -d \
-e WWWUSER=${WWWUSER} \
--entrypoint start-container \
--network "${DOCKER_NETWORK}" \
sail-7.4/app
printf "${GREEN}%s\n" "容器创建完成"
}
if [ "$1" = "run" ]; then# 创建数据库if [ "$2" = "--with-database" ]; then
create_database
fi# 创建容器
run_container
# 执行数据迁移if [ "$2" = "--with-database" ]; thenecho "执行数据迁移..."
docker exec -u sail -it "${DOCKER_CONTAINER_NAME}" /bin/bash -c "php artisan migrate --seed"fi# 系统访问地址printf "${NC}%s${GREEN}%s\n" "系统访问地址:" "${APP_URL}"
elif [ "$1" = "start" ]; then# 启动容器:echo "正在启动..."
docker start "${DOCKER_CONTAINER_NAME}"printf "${NC} %s ${BLUE} %s\n" "系统访问地址:" "${APP_URL}"printf "${GREEN} %s \n" "启动成功!"
elif [ "$1" = "enter" ]; then# 进入容器:
docker exec -it "${DOCKER_CONTAINER_NAME}" /bin/bash
elif [ "$1" = "stop" ]; then# 停止容器:echo "正在停止..."
docker stop "${DOCKER_CONTAINER_NAME}"echo "已停止!"
elif [ "$1" = "restart" ]; then# 重启容器echo "正在重启..."
docker restart "${DOCKER_CONTAINER_NAME}"printf "${GREEN}%s\n" "重启成功!"
elif [[ "$1" == "composer"* ]]; then# 在容器内执行 composer 命令
docker exec -u sail -i "${DOCKER_CONTAINER_NAME}" /bin/bash <<EOF
if [ "$(composer config -g -l | grep 'aliyun')" = '' ]; then
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer
fi
$*
EOF
else# 在容器内执行命令:
docker exec -u sail -it "${DOCKER_CONTAINER_NAME}" /bin/bash -c "$*"
fi
如果你想知道具体的实现原理,请参考代码注释,需要你熟悉 Docker 与 shell 脚本编程。
为脚本赋予可执行权限
在 Terminal 内,定位到项目目录下,执行以下命令:
chmod a+x my-sail.sh
构建容器
执行以下命令构建容器并同时创建数据库:
./my-sail.sh run --with-database
如果只构建容器,去掉 --with-database
参数即可:
./my-sail.sh run
看到以下界面,说明构建成功了:
将系统访问地址复制到浏览器打开,如果看到 Laravel 界面,说明运用运行环境创建成功了:
使用 my-sail 与容器交互
创建数据库迁移
./my-sail.sh php artisan make:migration create_test_table
运行结果:
查看PHP版本
./my-sail.sh php -v
运行结果
tinker终端
./my-sail.sh php artisan tinker
总之,就是需要在容器环境执行的命令,通通在前面加个 ./my-sail.sh
就行,非常简单,应该说比官方的实现容易得多。
管理容器
进入容器
./my-sail.sh enter
重启容器
./my-sail.sh restart
停止容器
./my-sail.sh stop
启动容器
./my-sail.sh start
感兴趣的朋友可以自己定制my-sail.sh
文件,可以提升自己的 Linux 基础水平。
好了,教程到此结束!有任何困难欢迎评论区留言。