laravel – apache – 設定 .htaccess 將網址移除 index.php 與強制轉向 http to https

目前我在 laravel 10 已經內建 .htaccess 只需要修改為

<IfModule mod_rewrite.c>
    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # 強制轉換 https
    RewriteCond %{HTTPS} off
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # 移轉 /index.php 到 /
    RewriteCond %{THE_REQUEST} \s/index\.php [NC]
    RewriteRule ^(?:[^/]+/)?index\.php(?:/(.*))?$ /$1 [L,R=301]

    # Send Requests To Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

上方實測可以解決

  1. http:// 轉換到 https://
  2. /index.php 轉換到 /
  3. 當有 route 名稱的時候,例如 /index.php/about 強制轉換到 /about

Docker 替換儲存的地方

一種是以直接修改 Docker Daemon 配置文件的方式,一種是用 rsync 的方式。基於安全,我建議使用 rsync 的方式。

使用 rsync 的方式

要知道 docker 的預設位置:

docker info | grep -i "docker root dir"

我在 ubuntu 會是 /var/lib/docker 。因為我的 /var/lib/docker 安裝在硬碟 sda2 容量不夠用,我希望移動到 sda3 的 /mnt/userdata/docker。以下提供完整的步驟來將 Docker 資料目錄從 /var/lib/docker 移動到 /mnt/userdata/docker,以釋放 sda2 的容量:

停止 Docker 服務

sudo systemctl stop docker

確保 /mnt/userdata 目錄存在,如果不存在,創建它

sudo mkdir -p /mnt/userdata

複製現有的 Docker 資料目錄到新的位置(這裡假設 sda3 已經掛載到 /mnt/userdata)

sudo rsync -aP /var/lib/docker/ /mnt/userdata/docker/

移動並作為備份原始的 Docker 資料目錄(強烈建議,之後沒問題再刪除)

sudo mv /var/lib/docker /var/lib/docker_backup

建立一個新的符號連結指向新的目錄

sudo ln -s /mnt/userdata/docker /var/lib/docker

啟動 Docker 服務

sudo systemctl start docker

確認 Docker 是否正確運作

sudo docker info

確認 /var/lib/docker 已經是符號連結到 /mnt/userdata/docker

ls -lh /var/lib/docker

如果一切正確,你應該能夠看到 /var/lib/docker 指向 /mnt/userdata/docker

使用 Docker Daemon

停止 docker 服務

sudo service docker stop

移動到新目錄,例如掛載的 mnt/userdata 底下

sudo mv /var/lib/docker /mnt/userdata/docker

修改配置文件,如果不存在就新增

sudo vim /etc/docker/daemon.json

添加以下內容

{
  "data-root": "/new/path/to/docker"
}

啟動 Docker 服務

sudo service docker start

ubuntu – 硬碟查詢與硬碟擴充方式

常用指令

// 列出硬碟的分割區表信息
sudo fdisk /dev/sda -l

// 確保你選擇了正確的硬碟 /dev/sda,然後使用 n 命令創建新的分割區,接著使用 p 確認分割區表,最後使用 w 寫入更改
sudo fdisk /dev/sda
n
p
w

// 將新建的分區 /dev/sda3 格式化為 ext4 文件系統
sudo mkfs.ext4 /dev/sda3

// 創建一個目錄 /mnt/userdata,你可以自行命名,像我開了一個 userdata,並將 /dev/sda3 分區掛載到這個目錄
sudo mkdir /mnt/userdata
sudo mount /dev/sda3 /mnt/userdata

// 永久掛載:為了確保在重新啟動後仍然掛載新分割區,需要在 /etc/fstab 檔案中新增一行。 開啟文件並新增以下一行:
sudo vim /etc/fstab

// 在文件末尾添加:
/dev/sda3   /mnt/userdata   ext4   defaults   0   2

// 重新啟動主機
sudo reboot
// 然後使用 df -h 或 sudo fdisk /dev/sda -l 確認新分區已成功掛載。

// 如果你想確認特定路徑(例如 /mnt/userdata)是否成功掛載,你可以使用這個命令。
df -h /mnt/userdata


Laravel 為什麼 Controller::method 的 Action 依照官方標準命名很重要?

官方提供了一個 Laravel 預設的命名標準:

https://laravel.com/docs/10.x/controllers#actions-handled-by-resource-controller

如果我們習慣在命名 method 依照 action 的分類命名,這樣在維護上會非常方便。

實務上依照 action 習慣命名,假如 BannerController 預設的 edit() 是編輯 Banner 相關資訊,可能我們還須要編輯某張圖片的介面,這時候如果不另外開新 Controller ,我就會 BannerController::ImageEdit() 這樣命名,使用後綴 (你也可以用前綴) 來增加辨識。好處是只要在 phpStorm 看整個方法,就可以精準掌握哪些 method 使用哪些動作,例如:

類似這樣,當我有一個驗證身份 (如 Laravel 的 Authorization),須要綁定所有新增的動作,我就可以直接快速找到要加入的 method 是哪些,例如下面須要在執行刪除的時候,添加驗證權限:

下面這個是在編輯的時候驗證權限:

完全可快速定位到 action 的 method,這樣在維護上就非常清爽啦!建議大家一定要習慣養成命名 action 的習慣。

laravel 在虛擬主機或共享主機使用 Schedule + command 的方法

在一些小型專案如果是買 web hosting or share hosting 的話,因為會有一些安全性限制,是無法在主機伺服器運行 exec 之類的指令,如果在 Schedule 使用這樣,那會噴錯

$schedule->command(
    CheckScheduleLiveCommand::class, [
        "message" => "1. 測試透過 Command 正常運行"
    ]
)->everyMinute();

上面這樣寫,會噴這樣的錯誤

[2023-10-21 13:31:02] production.ERROR: The Process class relies on proc_open, which is not available on your PHP installation. {"exception":"[object] (Symfony\\Component\\Process\\Exception\\LogicException(code: 0): The Process class relies on proc_open, which is not available on your PHP installation. at /home/powerstr/jetmonster.com.tw/laravel/vendor/symfony/process/Process.php:146)

原因是因為 php.ini (可以用 phpinfo(); 快速查看) 的 disable_functions 禁止使用 proc_open。但因為是共享主機啦,廠商通常也不會願意開放樣的限制,因此 Schedul 建議改用 call 這種寫法,全部交給 php 去執行時間上的判斷再去戳 command 的 script 會是最安全的做法。

// 在共享主機可以運行的作法
$schedule->call(function () {
    Artisan::call(
        CheckScheduleLiveCommand::class,
        [
            "message" => "4. 閉包 + Artisan 正常運行"
        ]
    );
})->everyMinute();

最後附上我的 Schedule 測試方法供參考

Log::debug("[---------- checkSchedule Start ----------]");

// 如果沒有值,但表伺服器可能阻擋了 exec 的指令
$schedule->command(
    CheckScheduleLiveCommand::class, [
        "message" => "1. 測試透過 Command 正常運行"
    ]
)->everyMinute();

$schedule->call(function () {
    Log::debug("2. 測試透過 call() 閉包");
})->everyMinute();

Artisan::call(CheckScheduleLiveCommand::class,
    ["message" => "3. 測試透過 Artisan 正常運行"]);


$schedule->call(function () {
    Artisan::call(
        CheckScheduleLiveCommand::class,
        [
            "message" => "4. 測試閉包 + Artisan 正常運行"
        ]
    );
})->everyMinute();