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

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

前提条件

已经通过教程构建好了 Laravel Sail 开发环境,并且已经具有了至少一个 搭建好的Laravel Sail 服务,没有构建好环境的朋友请参考文章开头提到的文章。首先打开 Docker Desktop,启动提前构建好的Laravel Sail 服务,笔者这里是kkyn_dcat_admin

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

拉取项目源码

进入 Ubuntu 子系统的项目目录\\wsl$\Ubuntu\home\myhui\projects,拉取项目源码:

git clone git@gitee.com:xxxxx/leona.git

注意:这里需要拉取你自己的源码

用 IDE(PhpStorm) 打开项目

同样,为了更快的运行速度,我们将项目放在 Ubuntu 子系统内部:
将老项目接入 Laravel Sail 服务的 MySQL 与 Redis 等服务

修改自己的 hosts 文件,配置开发域名

# 192.168.10.10 leona.test
127.0.0.1 leona.test

注意:如果之前你的开发域名是解析到 Homestead 的IP地址,必须把 Homestead 的IP解析注释掉或直接删除,否则会导致应用运行十分卡顿,参考《记一次 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
EOF
    printf "${GREEN}%s\n" "数据库${DB_DATABASE}创建成功"
}

# 创建容器函数
run_container(){
    echo "正在安装依赖..."
    composer install
    echo "生成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" ]; then
      echo "执行数据迁移..."
      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 基础水平。
好了,教程到此结束!有任何困难欢迎评论区留言。

本作品采用《CC 协议》,转载必须注明作者和本文链接
顺势而为
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 6

希望楼主出一篇使用 docker 部署 laravel 项目到服务器的文章

3年前 评论
myhui0926 (楼主) 3年前

file 楼主帮我看一下这个,要怎么才能访问 docker 容器的项目

3年前 评论
myhui0926 (楼主) 3年前
Witcier (作者) 3年前

这个多项目要怎么搞呢

3年前 评论
myhui0926 (楼主) 3年前
迷途的羔羊 (作者) 3年前
myhui0926 (楼主) 3年前

laravel sail 适用于生产环境么,通常生产服务器都是直接部署的环境,而且很多旧项目的laravel版本比较老,不能用laravel sail,本地的开发环境管理起来也比较混乱

3年前 评论
myhui0926 (楼主) 3年前
kwok_wah (作者) 3年前
myhui0926 (楼主) 3年前

这些$命令都在Ubuntu中操作???有很多疑问?

3年前 评论
myhui0926 (楼主) 3年前

问题一:按教程composer create-project laravel/laravel Example –prefer-dist “8.*”创建的项目少了vendor文件夹,两台电脑装了两次,都这样,在浏览器访问localhost提示没有’/../vendor/autoload.php’?不知道是网络原因,还是系统问题,还是安装过程?

详细:第一次按照laravel文档装在win10的C盘,有vendor;后来参照迁移教程重新安装一遍,就出现了问题一所述情况!查询搜索后出现vendor文件夹,解决过程如下:

  1. 按照教程,在Ubuntu命令projects目录下创建新项目
  2. composer install –ignore-platform-reqs 忽略php版本匹配
  3. curl -s https://laravel.build/example-app| bash(这里按8.5文档,创建新项目)
  4. ./vendor/bin/sail up (命令行接口,用于和 Laravel 默认 Docker 配置进行交互)-

问题二:对于问题一的解决是否正确,是否需要增改,原因不理解?
问题三:$ php artisan sail:install –with=mysql,redis这个命令是在ubuntu中安装mysql,redis?
问题四:发布 Dockerfile 以便定制,这节和之后都是在Ubuntu中执行?
问题五:容器已有,win10中还需要安装MySQL、composer?

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!