# 環境佈署相關

## 目錄結構
1. TBA

## 名詞解釋
1. DEV: 個人開發環境
2. PRE: 組內/與客戶的聯調預覽環境
3. PRO: 線上環境

## 流程
### DEV環境背景
0. 紀錄時間 2019-07
1. OS: Ubuntu 16.04.2 LTS
2. Apache: 2.4.18
3. Mysql: 5.7.27
4. PHP: 7.3.7-2
5. XDebug: 2.7.1
6. Composer: 1.8.6
7. Laravel: 5.5.4
8. 預設網頁根目錄: /var/www/html

### DEV環境建置(都以 root 的名義執行)
apt-get update # 更新軟體來源

apt-get install apache2 # 安裝 Apache 並啟動服務

apt-get install mysql-server mysql-client # 安裝 Mysql 並啟動服務，安裝過程中需要設定資料帳號 root 的密碼

apt-get install software-properties-common # 安裝 php 7.3 之前需要修改軟體來源

add-apt-repository ppa:ondrej/php # 加入 php 7.3 專用的軟體來源

apt-get update # 再次更新軟體來源

apt-get install php7.3 php-pear php7.3-curl php7.3-dev php7.3-gd php7.3-mbstring php7.3-zip php7.3-mysql php7.3-xml # 安裝 php 7.3 與相關 plugin

apt-get install php-xdebug # 安裝 XDebug

apt-get install curl zip lrzsz # 安裝其他常用的工具

apt-get install phpmyadmin # 安裝 phpmyadmin ，選擇 apache 以及啟用 dbconfig-common ，以及設定密碼

curl -s https://getcomposer.org/installer | php # 下載最新版 composer

mv composer.phar /usr/local/bin/composer # 安裝 composer

a2enmod rewrite # 啟用 Apache 目錄重定向模組，讓 laravel 目錄可以正常被解析

service apache2 restart # 重啟 Apache 使剛才的設定生效

php -i | grep ini | grep Configuration # 找出 php.ini 的路徑之後要修改設定 (假設是 /etc/php/7.3/cli/php.ini)

vi /etc/php/7.3/cli/php.ini # 編輯設定檔

```
; 在最後一行加入這個敘述
; 其中 dev 就對應名詞解釋章節中，當前環境的英文小寫，同理線上環境就是 pro
ogilvy.runtime.environment=dev

; 搜尋 error_log 開頭的這行，並且將開頭的分號註解移除，指定一個放置 error 訊息的路徑
error_log = /tmp/php_errors.log
```

### PRE/PRO環境背景與環境建置
1. 由於這些環境背景與建置方式取決於專案或客戶，所以不另行介紹，預設參考 DEV 環境。

### DEV上的基底程式建置(都以 root 的名義執行)
#### A. 上傳範例程式碼
cd /var/www/html # 切換到網頁根目錄

rz # 隨後選擇需要上傳的壓縮程式碼，例如 sampleProject.zip

unzip sampleProject.zip # 解壓縮

rm sampleProject.zip # 刪除壓縮檔

mv sampleProject ringeProject # 將資料檔名改成自己想要的名字，例如 ringeProject

#### B. 下載相依套件
cd /var/www/html/ringeProject # 切換進入專案資料夾

composer install # 安裝所有相依套件，存入新創建的 vendor 資料夾中

php artisan optimize # 最佳化相依套件的安裝(讓整體檔案變小)

#### C. 專案其他設定
cd /var/www/html/ringeProject # 切換進入專案資料夾

php artisan storage:link # 若專案有用戶創建的靜態內容，則需要有公開連結與對應的資料夾捷徑，它會在 public 資料夾下創建捷徑指向去 storage/app/public 資料夾中，之後的存取 URL 就會是 http://example.com/storage

php artisan key:generate # 重建 APP_KEY ，也就是 .env 文件中的 APP_KEY 部分

vi .env # 編輯預設的專案設定文件，但此文件不會被使用，之後需要拷貝成開發環境設定檔名

```
APP_ENV=dev                                                 # 本範例用在開發環境上所以指定為 dev ，但實際情況會用在預設的線上環境需要指定 pro
APP_KEY=base64:MtT8zoZvIJxglLOMY75wXScbK3rRcxPMHYQoiIvaGRQ= # 在下過 php artisan key:generate 指令後，此行會更新，需要同步到所有相關設定檔
APP_DEBUG=true                                              # dev 環境建議開啟，pro 環境建議關閉
APP_LOG_LEVEL=debug                                         # dev 環境建議指定 debug ，pro 環境建議指定 info
APP_URL=http://ringeProject.ogilvy.com.tw                   # 建議使用 xxx.ogilvy.com.tw 的命名方式(另有教學會指定讓該網址生效)，避免開發環境太多臨時專案都用 localhost 產生衝突
APP_NAME=ringeProject                                       # 可填寫程式資料夾的名字，不會被網頁的任何地方顯示

DB_CONNECTION=mysql                                         # 此行基本上不需要改，用 mysql/maria 都適用
DB_HOST=127.0.0.1                                           # 若按照教學進行則可指定本機，不然可視當前環境另外指定
DB_PORT=3306                                                # mysql 預設的 port 可不用修改
DB_DATABASE=ringeProject                                    # 指定連接的資料庫名稱，可視環境修改
DB_USERNAME=root                                            # mysql 帳號
DB_PASSWORD=root                                            # mysql 密碼

BROADCAST_DRIVER=log                                        # 不需修改或視情況修改
CACHE_DRIVER=file                                           # 不需修改或視情況修改
SESSION_DRIVER=file                                         # 不需修改或視情況修改
QUEUE_DRIVER=sync                                           # 不需修改或視情況修改
```

cp .env .env.dev # 拷貝成實際的專案設定文件，結尾的 .dev 對應名詞解釋章節中，當前環境的英文小寫，同理線上環境就是 .pro

cp .env .env.pre # 拷貝成預覽環境的專案設定文件，之後需要另外調整內容，本範例不介紹

cp .env .env.pro # 拷貝成線上環境的專案設定文件，之後需要另外調整內容，本範例不介紹

chmod -R 777 storage # 修改 storage 文件夾讓網頁伺服器有權限寫入數值

#### D. 匯入資料庫

cd ~/ # 切換回家目錄

rz # 隨後選擇需要上傳的資料庫 schema ，例如 tableSchema.sql

sed "s/sampleProject/ringeProject/g" tableSchema.sql > ringeProject.sql # 將範例資料庫改成在 laravel 設定檔中指定的庫名並以庫名當成檔名保存

mysql -uroot -p < ringeProject.sql # 匯入資料庫

rm -f *.sql # 移除這些 schema

vi /etc/mysql/conf.d/mysql.cnf # 編輯 mysql 設定檔，在最底下加入這個，讓後台選單功能 SQL 可以順利

```
[mysqld]
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
```

service mysql restart # 重啟 mysql

#### E. 剩餘配置

vi /etc/apache2/sites-available/ringeProject.conf # 創建專案的 apache 配置文件，請視內容修改成自己的專案名稱

```
<VirtualHost *:80>
	ServerAdmin  ringech.chen@ogilvy.com     # 改成自己的信箱
	ServerName   ringeProject.ogilvy.com.tw  # 改成 xxx.ogilvy.com.tw 這樣的格式
	DocumentRoot /var/www/html/ringeProject/public
	<Directory  "/var/www/html/ringeProject/public">
		Options FollowSymLinks
		AllowOverride All
	</Directory>
	php_value xdebug.remote_port 7900 # 這個是開發環境 xdebug 用的 port ，避免跟其他人或其他專案混淆一律採取 [分機後2碼+累加編號: 例如 7900]，後面章節會詳述
	ErrorLog  ${APACHE_LOG_DIR}/ringeProject.error.log
	CustomLog ${APACHE_LOG_DIR}/ringeProject.access.log combined
</VirtualHost>
```

a2ensite ringeProject # 啟動該配置文件

service apache2 reload # 重載入 Apache 使剛才的設定生效
改成
接著編輯自己的操作電腦(並非 Ubuntu 那台)，編輯它的 host 文件(舉例 windows 系統放在 C:\Windows\System32\drivers\etc\hosts)，於文件末端加入一行

```
10.10.10.10 ringeProject.ogilvy.com.tw # ringeProject 的 dev 環境 (修改成 dev 伺服器的 IP 以及自己指定的命名空間)
```

之後在自己的操作電腦打開瀏覽器，輸入 http://ringeproject.ogilvy.com.tw/backend/login 登入驗證架設是否成功，預設登入的帳密: admin@example.com / onemispwd23525008

### DEV上的程式開發調適

#### A. 錯誤訊息路徑整理
tail -f 錯誤日誌路徑 # 這個指令方便及時觀察錯誤日誌

```
/var/www/html/sampleProject/storage/logs/laravel.log # 程式等級的錯誤訊息，例如資料夾權限， mysql 權限等等，通常在瀏覽器執行時會有較詳細的頁面
/tmp/php_errors.log # php 語法等級的錯誤，像是堆疊溢位，正規表達無限迴圈等等
/var/log/apache2/ringeProject.error.log # 伺服器等級的錯誤
/tmp/xdebug.log # xdebug 日誌
```

#### B. 除錯(使用 Tool=Xdebug + IDE=Phpstorm 作為範例)

##### 伺服器端的 Xdebug 設定
vi /etc/php/7.3/mods-available/xdebug.ini # 修改配置文件加入以下內容，若沒有此文件也可以修改 php.ini(但需要微調配置內容)

```
xdebug.remote_autostart = 1
xdebug.remote_enable = 1
xdebug.remote_handler = "dbgp"
xdebug.remote_host = "127.0.0.1" 
xdebug.remote_log = "/tmp/xdebug.log"
xdebug.remote_cookie_expire_time = 36000
```

service apache2 restart # 重啟動 Apache 使剛才的設定生效

##### 操作端的 port mapping 設定(使用 Windows 7 作為範例)
需要先下載 [plink](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html)

plink -ssh -L 7900:127.0.0.1:7900 -pw 開發機的密碼 -N 開發機的帳號@開發機的IP # 打開 cmd 下這個指令即可將本地 phpstorm 的監聽 port 轉移到開發機上的 localhost 對應的 port

##### 操作端的 Phpstorm 設定

1. File > Settings > Language & Framework > PHP > Debug > Xdebug > Debug Port > 填寫之前章節指定的 7900 連線埠

2. File > Settings > Build, Execution, Deployment > Deployment > + > 填入程式碼發布資訊
	1. Name:                         ringeProject
	2. Connection > Type:            SFTP
	3. Connection > SFTP Host:       填入開發機器的IP
	4. Connection > Port:            填入開發機器的PORT
	5. Connection > Root path:       /
	6. Connection > User name:       填入開發機器的帳號
	7. Connection > Auth Type:       Password
	8. Connection > Password:        填入開發機器的密碼
	9. Connection > Web root URL:    http://ringeProject.ogilvy.com.tw
	10. Mappings   > Local path:      操作端電腦專案的根目錄
	11. Mappings   > Remote path:     伺服器端電腦專案的根目錄
	12. Mappings   > Web path on ..:  /

3. File > Settings > Build, Execution, Deployment > Deployment > Options > Upload Changed files ...: 選擇Ctrl + S ，之後操作端保存程式碼的時候，IDE 就會自動上傳到開發環境即時生效


4. File > Settings > Language & Framework > PHP > Servers > + > 填入程式碼路徑對應資訊
	1. Name: ringeProject
	2. Host: ringeproject.ogilvy.com.tw
	3. Port: 80
	4. Use path mapings: 打勾
	5. Absolute path on the server: /var/www/html/ringeProject

5. 右上方除錯箭頭 > Edit configurations > + > PHP Web Page >
	1. Name:      ringeProject
	2. Server:    選擇剛才建立的 ringeProject
	3. Start URL: http://ringeProject.ogilvy.com.tw/

6. 詳細的官方教學 [看這邊](https://www.jetbrains.com/help/phpstorm/configuring-xdebug.html)

### PRE/PRO上的程式佈署
pre 環境選擇性使用手動上傳檔案或者使用版控

pro 環境希望能夠做到全部使用版控

具體細節參閱版控資料夾裡面的說明

### PRE/PRO上的程式調適
參閱「錯誤訊息路徑整理」章節，需要先行在這些環境上的配置文件中找出所有的除錯所需路徑，由於線上環境沒有 xdebug 所以這些路徑會幫助定位問題

### 其他注意事項

