教你將新舊專案接入已建立好的 Laravel Sail 容器(MySQL、Redis)

myhui0926發表於2021-07-08

自發布 《將 Laravel 開發環境由 Homestead 遷移到 Laravel Sail ( Docker ) 完整詳細教程》 這篇文章以來,已經有 1900 多個閱讀了,看來大家都在積極擁抱 Laravel Sail 開發環境,開始逐步淘汰 Homestead了。

但是 Laravel Sail 開發環境僅支援 Laravel8 ,然而很多老一點的專案是基於5 - 7版本的。對於這些專案,我們只要自己構建一個執行容器接入 Sail 建立好的 MySql、 Redis等容器,可以所有開發環境都統一到 Laravel Sail 了。筆者就是這麼做的,我已經很久沒有開啟過 Homestead 這個重量級開發環境了。

當然,即使是基於 laravel8 的新專案,你可能不願意再次搭建和編排新的MySQL、Redis 容器,或者多個專案之間需要使用相同的 MySQL、Redis 容器,這篇文章都適合你。

對於有 Linux 基礎和 Docker 基礎的人來說,自己完全可以獨立構建映象並編排執行容器。但對於很多 Linux 和 Docker 知識不是很牢靠的開發者而言,寫一篇簡單易懂的入門接入教程還是很有必要的。讓我們開始吧,我們將從拉取專案程式碼開始,一步一步教你接入已精通sail構建好的MySQL、Redis映象。

假如我們現在有一個基於 Laravel7 開發的應用 Leona,我將一步一步教你接入 Laravel Sail 。

已經通過教程構建好了 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

注意:這裡需要拉取你自己的原始碼

同樣,為了更快的執行速度,我們將專案放在 Ubuntu 子系統內部:
將老專案接入 Laravel Sail 服務的 MySQL 與 Redis 等服務

# 192.168.10.10 leona.test
127.0.0.1 leona.test

注意:如果之前你的開發域名是解析到 Homestead 的IP地址,必須把 Homestead 的IP解析註釋掉或直接刪除,否則會導致應用執行十分卡頓,參考《記一次 hosts 檔案配置錯誤導致應用卡頓的奇葩問題》

回到專案 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
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 等服務

為了方便我們構建容器並與容器互動,我們參照 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" "容器建立完成"
    echo "執行資料遷移..."
    docker exec -u sail -it "${DOCKER_CONTAINER_NAME}" /bin/bash -c "php artisan migrate --seed"
    printf "${NC}%s${GREEN}%s\n" "系統訪問地址:" "${APP_URL}"
}

if [ "$1" = "run" ]; then
    # 建立資料庫
    create_database
    # 建立容器
    run_container
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" "重啟成功!"
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

看到以下介面,說明構建成功了:

將老專案接入 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 協議》,轉載必須註明作者和本文連結
順勢而為

相關文章