将新项目接入Laravel Sail 创建好的MySQL、Redis容器,并实现自己的 sail 脚本与容器交互

Laravel框架
669
0
0
2022-05-12
标签   Laravel环境

自发布 《将 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

为了小白不犯错,放个截图:

将老项目接入 Laravel Sail 服务的 MySQL 与 Redis 等服务

参考以下的环境变量(.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项:
将老项目接入 Laravel Sail 服务的 MySQL 与 Redis 等服务
同时为了能够在 MySQL 容器内自动创建所需的数据库,需要知道之前构建好的 MySQL 容器的名称,可以通过 Docker Desktop 查看自己的 MySQL 容器名称,并将容器名称配置给MYSQL_CONTAINER_NAME环境变量:
将老项目接入 Laravel Sail 服务的 MySQL 与 Redis 等服务

写一个简易的 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 Sail 服务的 MySQL 与 Redis 等服务

将系统访问地址复制到浏览器打开,如果看到 Laravel 界面,说明运用运行环境创建成功了:

将老项目接入 Laravel Sail 服务的 MySQL 与 Redis 等服务

使用 my-sail 与容器交互

创建数据库迁移

./my-sail.sh php artisan make:migration create_test_table

运行结果:

将老项目接入 Laravel Sail 服务的 MySQL 与 Redis 等服务

查看PHP版本

./my-sail.sh php -v

运行结果

将老项目接入 Laravel Sail 服务的 MySQL 与 Redis 等服务

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 基础水平。

好了,教程到此结束!有任何困难欢迎评论区留言。