# 前言
Laradock 使用筆記
# 安裝
- 安裝 git (若無)
- clone 專案, 可參考 官方文件
# Laradock 架構
# 已經有一個專案
參考 官方文件
# 還沒有專案
參考 官方文件
# 多專案
可參考 官方文件
下面主要針對多專案來解說, 需求是
- 一個 Laradock 資料夾
- N 個專案
- 可以使用不同的 PHP 版本
- 可以使用不同類型或版本的 DB (多專案若使用同版本 DB, 共用一個 connection)
- 可使用 PHP Unit test
- 支援 PHPStorm unit test 功能
- 支援 APC cache
- 可在 container 內呼叫自己, 而非 host (用於 testing)
# Laradock 位置
位置隨意, 想放哪都可以
# env 檔設定
預設不會有 .env file, 要 copy Laradock 資料夾內的 env-example to .env
copy env-example .env |
接下來, 為了實現多專案, 所以我們建一個資料夾, 裡面專放各個專案的 .env, 即每個不同專案的環境資訊, 這個資料夾放哪都行
接著, 在該資料夾內, 除了從預設 env-example
複製過來的 .env
, 為了區別預設環境跟各個專案獨有的環境設定, 我們新增一個 .env.custom
, 內容如下
#################### 以下為客製化選項##################### |
當設定好 .env.custom
後, 可將其內容 append 到預設的 .env
, 這樣比較清楚到底改了什麼
cat .env.custom >> .env |
# MySQL 設定
# 若擔心 collation 問題, 可設定 my.cnf, 基本上不需要
my.cnf (與 create.sql 擇一即可)
vim laradock/mysql/my.cnf
加入以下設定
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
collation-server = utf8_unicode_ci
init-connect='SET NAMES utf8'
character-set-server = utf8
# 除了 my.chf, 也可使用 create.sql, 擇一即可
修改
vim laradock/mysql/docker-entrypoint-initdb.d/createdb.sql
內容
SET CHARACTER_SET_CLIENT=utf8mb4;
SET CHARACTER_SET_RESULTS=utf8mb4;
SET CHARACTER_SET_database= utf8;
SET COLLATION_CONNECTION=utf8_unicode_ci;
# 驗證方式
因為 PHP 7.3 之前的版本並不支援 MySQL 8 的密碼驗證方式, 可參考, 若非得使用舊版本 PHP 新版本 MySQL 的組合的話, 如下設定
修改 my.cnf
vim laradock/mysql/my.cnf
內容
[mysqld]
default_authentication_plugin= mysql_native_password如修改無法生效, 需把 MySQL 的檔案刪除重建, 這會把該版本資料庫所有資料都刪除, 慎用, 目標為 .env 中設定的
DATA_PATH_HOST
rm -rf /path/to/yourDataLocation
# 建立 Database, 只有該版本第一次建立有效
複製範例檔
cp laradock/mysql/docker-entrypoint-initdb.d/createdb.sql.example laradock/mysql/docker-entrypoint-initdb.d/createdb.sql
批量新增資料庫
uncomment 以下的設定檔, 並將dev_db_1
… 換成自己需要的資料庫名字#CREATE DATABASE IF NOT EXISTS `dev_db_1` COLLATE 'utf8_general_ci' ;
#GRANT ALL ON `dev_db_1`.* TO 'default'@'%' ;
#CREATE DATABASE IF NOT EXISTS `dev_db_2` COLLATE 'utf8_general_ci' ;
#GRANT ALL ON `dev_db_2`.* TO 'default'@'%' ;
#CREATE DATABASE IF NOT EXISTS `dev_db_3` COLLATE 'utf8_general_ci' ;
#GRANT ALL ON `dev_db_3`.* TO 'default'@'%' ;
# 更改帳號密碼, 只有該版本第一次建立有效
vim laradock/.env |
搜尋 MySQL
並將 default user 的密碼以及 root 的密碼更改
# 專案配置
# .env
修改專案的 .env, 非 Laradock .env
vim yourProject/.env
更改 DB_HOST 為
mysql
更改 DB_DATABASE 設為該專案使用的資料庫, 如果使用的資料庫版本之前已經有建立過, 只是沒有該資料庫, 那 build 過程是不會主動建立的, 要手動連接到資料庫建立, 方可使用
更改 DB_USERNAME 為
default
(可自定義)更改 DB_PASSWORD
# 修改 storage 權限, 預設應該是不用改
sudo chmod -R 777 storage bootstrap/cache |
# Supervisor
當我們有使用 queue 或是 scheduler 的功能時, 會需要在背景起一個 process 用來監聽 queue job, 這時便需要使用程序管理器, 像是 supervisor 或 pm2
Laradock 已內建 supervisor 可以使用, 相當方便。
# 用法
- 切換到
Laradock/php-worker
目錄中, 可依據需求修改Dockerfile
以及supervisord.conf
, 若無需求不需修改 - 建立 config 檔,
cp *.conf.example *.conf
- 啟動
docker-compose up -d php-worker
# 設置 NGINX
如果是本地開發的話, 基本上預設即可, 若要用於 production, 需設定相對應 server name
# 重導 HTTP 到 HTTPS |
# network alias 修改
如果有跑測試, 可能會需要通過 guzzle 呼叫一些內部才可呼叫的 API, 例如清除 apc cache, 因為在 container 內的 curl localhost 會被指到 host machine 的 localhost, 這樣就無法將 request 導向正確的地方
所以必須要在 docker-compose.yml file 做一些修改, 如下, 之後只要在 APP 內呼叫該 domain, 那就會映射到 container 的 localhost
### NGINX Server ### |
# 啟動 Laradock
啟動 Laradock 時, 我們可根據不同的 .env file 來啟動適用於不同專案的 Laradock 環境, 可將下面的冗長指令設定成 alias, 即可透過不同的 alias 來管理不同專案的 Laradock 環境
# build
完成一切設定後, 重新 build Laradock, 如果 MySQL connection 已存在, 可以不需重新 build, 如果沒有更動到預設設定的, 也不需 build
這邊需針對各個專案來指定 .env
docker-compose -f /path/to/yoruLaradockLocation/docker.compose.yml --env-file /path/to/yourProjectEnv build --parallel --no-cache workspace mysql php-fpm nginx redis php-worker |
# up
結束 build 後, 就可以 up Laradock 環境
docker-compose -f /path/to/yoruLaradockLocation/docker.compose.yml --env-file /path/to/yourProjectEnv up -d workspace mysql php-fpm nginx redis php-worker |
# down
若要刪除環境, 可使用 down
docker-compose -f /path/to/yoruLaradockLocation/docker.compose.yml --env-file /path/to/yourProjectEnv down |
# down
若要 stop container, 但不刪除 container, 通常專案之間切換環境並不需要刪除 container, stop 就行 (主要避免 workspace 與 nginx port 衝突而已)
docker-compose -f /path/to/yoruLaradockLocation/docker.compose.yml --env-file /path/to/yourProjectEnv stop workspace mysql php-fpm nginx redis php-worker |
# 執行專案前設置
務必要設定好 .env 中的 MySQL_HOST, 以及 Redis_HOST, 都要改成 mysql 以及 redis, 因為 Laravel .env 中預設的 host 位置為 host machine 的通常環境, 但在 container 中, 不同的 container 處於同一個 network, 但並不處於同一個 node, 而 Laradock 是將不同的 container 服務 alias 成 domain name, 所以 mysql 即代表 mysql container 的 IP 位置
# Laradock 環境下的 artisan 以及 composer
試想, 如果你的機器非常乾淨, 只裝了用來 pull Laradock 的 Git, 其他什麼都沒裝, 那你電腦中自然也不會有 composer, php, 所以要執行這些 command 就需要透過 docker
docker-compose -f /path/to/yoruLaradockLocation/docker.compose.yml --env-file /path/to/yourProjectEnv exec workspace php artisan key:generate |
# Unit test 資料庫
如果有使用到 TEST, 記得到資料庫中建立一個 for testing 的資料庫, 然後在 .env.test
中設置相對應的參數, 當然, 我們都是使用 container 中的資源, 所以 host, password, user 那些務必都要改成 DB container 的參數
# APC cache
Laradock 只提供了 PHP-FPM 中安裝 APC driver, 但並不支援 workspace 安裝 APC driver, 所以當跑測試時, 測試跑的是 CLI 環境, 並不透過 PHP-FPM, 因此如果有使用到 APC Cache 功能的地方就會噴錯, 因此我們必須手動到 workspace 中安裝 APC Cache
apt update && apt install php-apcu |
# PHPStorm
PHPStorm 預設 testing configuration 是使用 Local 的 PHP Interpreter, 但我們 host machine 並沒有安裝 PHP, 只有 Laradock, 再者, 我們會需要 PHPStorm 是在 workspace container 中下達運行, 這樣才會使用到相對應的 DB
# SSH
- 先到 PHPStorm 的 Preference -> Tools -> SSH Configurations, 完成以下設定, 可參考 官網
# PHP Interpreter
- 接著到 Preference -> Languages & Framework -> PHP 頁面中, 設定 CLI Interpreter, 選取
...
, 如下設定
# PHP Testing Configuration
接著到 Preference -> Languages & Framework -> PHP -> Test Frameworks 設定
CLI Interpreter
,composer autoload
,phpunit.xml
完成以上設定後, 應該就可以使用 testing 功能, 我的 short cut 是
shift
+ctrl
+r
# Jenkins
# 設定
簡易個人 side project 用的 CD 可參考 這篇文章
Shell Script
- 從容器連到欲部署的 Server
ssh -i /var/jenkins_home/yourDeployKey root@yourServerIP \
"cd /yourProjectLocation/ && \\
git reset @^ --hard && git pull \\
&& cd /laradockProjectLocation/ \\
&& /usr/bin/docker-compose exec -T --user=laradock workspace php /var/www/yourProjectName/artisan migrate --force \\
&& /usr/bin/docker-compose exec -T --user=laradock workspace composer install -d /var/www/yourProjectName \\
&& /usr/bin/docker-compose exec -T --user=laradock workspace php /var/www/yourProjectName/artisan queue:restart \\
&& /usr/bin/docker-compose exec -T --user=laradock workspace php /var/www/yourProjectName/artisan db:seed"
# Add Swap Space
當部署的機器 Memory 較低時, 常常會把 RAM 耗光, 這時我們可以通過切割一部分沒用到的硬碟給 RAM
作業系統
ubuntu 18.04確認目前 swap 大小, 如果沒有輸出, 代表目前 server 沒有劃分這一塊, 可以加了
sudo swapon --show
建立 Swap 檔案
- fallocate: 切割硬碟給檔案
- -l: length, 檔案大小
- /swapfile: 檔案
sudo fallocate -l 1G /swapfile
設定正確的權限
sudo chmod 600 /swapfile
設定 Swap Space
- mkswap: 建立 swap 區域, 可以是 disk partition, 也可以是一個檔案
sudo mkswap /swapfile
- mkswap: 建立 swap 區域, 可以是 disk partition, 也可以是一個檔案
輸出:
Output
Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
no label, UUID=f59595fb-754b-47ae-af6b-8dd6e98654d8啟用 Swap Space
sudo swapon /swapfile
確認 swap 是否已可被使用
sudo swapon --show
輸出
Output
NAME TYPE SIZE USED PRIO
/swapfile file 1024M 0B -2確認可用使用量
free -h
輸出
Output
total used free shared buff/cache available
Mem: 581M 275M 62M 103M 243M 110M
Swap: 1.0G 0B 1.0G使 Swap 永久有效
sudo vim /etc/fstab
增加以下代碼到檔案中
/swapfile swap swap defaults 0 0
設定 swappiness
swappiness 為 0 時, kernel 將不會將 data 換到 disk 除非真的有必要, 值越高時 kernel 會盡可能地將 data 放到 swap, 讓 RAM 更空一點
所以, 告訴系統盡量不要依賴 swap 可以讓系統運行的快一點
查看目前的 swappiness
cat /proc/sys/vm/swappiness
輸出
Output
60將 swappiness 設定為 10
sudo sysctl vm.swappiness=10
輸出
Output
vm.swappiness = 10持久化 swappiness
sudo vim /etc/sysctl.conf
加入下面這一行
vm.swappiness=10
移除 Swap Space
sudo swapoff -v /swapfile
從 /etc/fstab 移除上面加入的代碼
/swapfile swap swap defaults 0 0
最後, 刪除 swap 檔案
sudo rm /swapfile
# PHP-WORKER
Laradock 預設 php-worker 以及 Horizon 都是不支援 MSSQL 的, 所以自己根據專案需求改了一下 php-worker 的 docker file, 目前只測過 php7.4 是可用的, 其他版本沒測過
https://github.com/tn710617/laradock
# 非正規設置法 (自己弄好玩的, 勿學 XD)
以下是個人配置, 旨在利用 Let’s Encrypt Certbot 自動每三個月續簽 SSL 憑證, 並自動套用到每個專案
所以會在 Host 處安裝 NGINX + CertBot, 因為自動續簽 SSL 憑證會用到 NGINX 80 port, 所以容器外的 NGINX 會監聽 80 port, 並把符合條件的請求都導向由容器直接監聽的 443 port, 所以會在容器內外都安裝 NGINX
# NGINX 配置
因為 Let’s Encrypt 在自動續簽的過程中, CertBot 會 restart NGINX, 所以 NGINX 會分成容器內跟容器外
# 容器內 NGINX
// 容器外的 NGINX 會將指定 server_name 的流量導向 443 port, 所以這邊不需監聽 80 port |
# 容器外 NGINX
// 容器外相當簡單, 將來自 80 port 的請求導向 443 即可
server { |
# Let’s Encrypt
安裝可參考 取得 wildcard SSL 憑證
# 其他配置檔
# docker-compose.yaml
取拿掉 80 port 對應, 因為 80 port 會由容器外的 NGINX 監聽
ports: |
# Laradock 的 .env
// 因為 80 port 沒開, 所以參數也不需設定 |
留言