Laravel - 部署

# Introduction

記錄一些 Laravel 部署的相關設定以及步驟


# 環境資訊

AWS EC2
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

# 部署目標主要套件版本

  • Laravel 8
  • PHP 7.4
  • Nginx 1.16
  • MySQL 8

# 新增 yum 源站以及更新

sudo yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
sudo yum -y install https://rpms.remirepo.net/enterprise/remi-release-7.rpm
sudo yum -y install yum-utils
sudo yum-config-manager --enable remi-php74
sudo yum update

# Nginx

# 安裝

sudo yum -y install nginx

# 啟動

sudo systemctl start nginx

# 開機自動啟動或不自動啟動

sudo systemctl enable nginx
sudo systemctl disable nginx

# 確認狀態

sudo systemctl status nginx

# 確認語法是否正確

sudo nginx -t

# sites-available, sites-enabled 資料夾

# 建立

sudo mkdir /etc/nginx/sites-available
sudo mkdir /etc/nginx/sites-enabled

# 修改設定檔

sudo vim /ete/nginx/nginx.conf
# Load customized enabled sites
include /etc/nginx/sites-enabled/*;
sudo ln -s /etc/nginx/sites-available/yourProjectConf /etc/nginx/sites-enabled/

# 權限配置

sudo chown -R nginx:nginx /var/lib/nginx

# 重新安裝 (若有需要)

# 完全移除 Nginx

sudo systemctl stop nginx.service
sudo systemctl disable nginx.service
sudo userdel -r nginx
sudo rm -rf /etc/nginx
sudo rm -rf /var/log/nginx
sudo rm -rf /var/cache/nginx/
sudo rm -rf /usr/lib/systemd/system/nginx.service
sudo yum remove nginx

# 重新安裝

sudo groupadd nginx
sudo useradd -g nginx nginx -s /sbin/nologin
sudo yum -y install nginx

# Apache

# 安裝 Apache

sudo yum -y install httpd24

# 啟動

sudo service httpd start

# 設定開機自動重啟

sudo chkconfig httpd on

# 確認 httpd 已啟用

chkconfig --list httpd

# 設定檔

sudo vim /etc/httpd/conf/httpd.conf
<Direction "/var/www/yourProject">
Allow Override All
</Direction>

# 安裝 SSL module

sudo yum install mod24_ssl

# AWS

# 設定 security inbound


# 測試 LAMP Web 伺服器

# 在 /var/www/html 資料夾中建立 PHP info

echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php

# 訪問 http://ip/phpinfo.php

# 刪除

rm /var/www/html/phpinfo.php

# PHP

# 安裝

  • PHP

    sudo yum install php 
  • PHP Extensions

    sudo yum install php-fpm php-mysqlnd php-devel php-gd php-mbstring php-xml php-pear php-bcmath php-opcache
    sudo pecl channel-update pecl.php.net
    sudo pecl install imagick
  • 其他套件

    sudo yum install ImageMagick ImageMagick-devel ImageMagick-perl 

# 啟動 PHP-FPM

sudo systemctl start php-fpm

# 開機自動啟動或不自動啟動 PHP-FPM

sudo systemctl enable php-fpm
sudo systemctl disable php-fpm

# 若要變更 Listen port 9000 到 socket

  • 編輯

    sudo vim /etc/php-fpm.d/www.conf
  • 內容

    ; listen = 127.0.0.1:9000
    listen = /var/run/php/php7.4-fpm.sock

# 變更 php-fpm child process user

  • 編輯

    sudo vim /etc/php-fpm.d/www.conf
  • 內容

    user = php
    group = php

# 變更 php-fpm sock owner 以及權限

  • 編輯

    sudo vim /etc/php-fpm.d/www.conf
  • 內容

    listen.owner = yourPreferredOwner
    listen.group = yourPreferredGroup
    listen.mode = 0660

# 開機自動建立 /var/run/php

  • 編輯

    sudo vim /usr/lib/tmpfiles.d/yourPreferredDaemonName.conf
  • 內容

    #Type Path            Mode UID      GID    Age Argument
    d /run/mydaemon 0755 myuser myuser - -

# 變更 php-fpm child process user umask

sudo systemctl edit php-fpm.service

系統會自動在 /etc/systemd/system/php-fpm.service.d 生成一個新的 override.conf 檔, 任何在此檔內的設定都會優先使用
也可修改 /lib/systemd/system/php-fpm.service 檔案, 不過如果系統更新, 可能會覆蓋掉這個設定

[Service]
UMask=0002

然後重啟

sudo systemctl reload php-fpm.service
sudo systemctl restart php-fpm

# MySQL

# 設定 yum repository

sudo rpm -Uvh https://repo.mysql.com/mysql80-community-release-el7-3.noarch.rpm

# disable 預設 yum MySQL repo

sudo sed -i 's/enabled=1/enabled=0/' /etc/yum.repos.d/mysql-community.repo

# 指定 yum mysql repo 並安裝

sudo yum --enablerepo=mysql80-community install -y mysql-community-server

# 啟動

sudo systemctl start mysqld

# 確認是否啟動

sudo systemctl status mysqld

# 取得臨時 root 密碼

sudo grep "A temporary password" /var/log/mysqld.log

# 完成安全設定

sudo mysql_secure_installation

# 針對專案建立使用者

# 建立

CREATE USER 'userName'@'userHost' IDENTIFIED BY 'userPassword';

# 賦予權限

GRANT ALL ON databaseName.tableName TO 'userName'@'hostName'

# 使用 RDS

  • MySQL client
    mysql -h yourHost -u yourUser -p

# Git

# 安裝

sudo yum install -y git

# 設定可接受遠端 push

sudo git config receive.denyCurrentBranch ignore

# 設定 hook

sudo vim /var/www/projectName/.git/hooks/post-receive
GIT_WORK_TREE=/var/www/projectName git checkout -f
cd /var/www/projectName
/usr/local/bin/composer install

/usr/bin/php artisan migrate

/usr/bin/php artisan config:clear
/usr/bin/php artisan config:cache

/usr/bin/php artisan route:clear
/usr/bin/php artisan route:cache
chmod 770 post-receive

# Composer

# 安裝 dependency

sudo yum install php-cli php-zip wget unzip

# 下載 Composer installer

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"

# 驗證 installer 是否正確

HASH="$(wget -q -O - https://composer.github.io/installer.sig)"

php -r "if (hash_file('SHA384', 'composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"

# 安裝

sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer

# 專案

# 查看 nginx user

ps aux | grep nginx

# 查看 fpm user

ps aux | grep fpm

# 建立資料夾

sudo mkdir /var/www/projectName

# 建立之後將管理專案的 group

sudo groupadd projectName

# 將會存取到該專案的使用者加到該群組

sudo usermod -a -G projectGroupName userName(user,nginx,php-fpm)

# 修改專案資料夾目錄權限(使用上面建立的 group)

sudo chown -R root:projectGroupName /var/www/projectName
sudo chmod 2770 /var/www/projectName
sudo find /var/www -type d -exec sudo chmod 2770 {} \;
sudo find /var/www -type f -exec sudo chmod 0660 {} \;
sudo chmod 770 /var/www/projectName/artisan
sudo chmod 770 /var/www/projectName/.git/hooks/post-receive

# 本機 push 到機器上

# 增加新的 remote

git remote add remoteName sshKeyUserName@serverIp:/var/www/projectName

# push

GIT_SSH_COMMAND='ssh -i ~/.ssh/serverLoginPrivateKey' git push test master

# 專案啟動設置

  • 設置 .env
  • 產生 key
    php artisan key:generate
  • 匯入 tables
    php artisan migrate

# Redis

# 安裝

sudo yum install redis
sudo yum install php-pecl-redis

# 啟動

sudo systemctl start redis
sudo systemctl status redis

# 開機自動啟動或不啟動

sudo systemctl enable redis
sudo systemctl disable redis

# 使用 ElastiCache

  • .env

    REDIS_HOST=tls://yourHost
    REDIS_PASSWORD=yourPassword
    REDIS_PORT=6379
  • redis-cli
    在 ec2 上無需使用 -a 便可登入

    redis-cli -c -h yourHost -a yourAuth --tls

# SELinux

# 確認 SELinux 是否開啟

sudo getenforce

# HTTP 讀取權限

# 查看 project SELinux 設定

ls -Zd /var/www/projectName

# 賦予 storage, cache 資料夾讀寫權限

sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/projectName/storage(/.*)?"
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/projectName/bootstrap/cache(/.*)?"
  • -a: 增加規則到預設安全性本文

  • -m: 呈上, 修改

  • -d: 呈上, 刪除

  • -t: type

# 恢復預設

sudo restorecon -Rv '/usr/share/nginx/html/testapp'
  • -R: recursive
  • -v: verbose

# 允許 HTTP 連結資料庫 (For database)

sudo setsebool -P httpd_can_network_connect_db 1
  • -P:直接將設定值寫入設定檔

# 允許 HTTP 連結 socket (For local redis)

sudo setsebool -P httpd_can_network_connect 1
  • -P:直接將設定值寫入設定檔

# Supervisor

# 安裝

sudo yum install supervisor

# 執行 worker 的 user

# 建立

sudo useradd userName -s /sbin/nologin

# 賦予專案權限

sudo usermod -a -G projectGroupName workerUserName

# 建立配置 worker ini 檔

sudo vim /etc/supervisord.d/laravel-worker.ini
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=/path/to/php /path/to/yourProject/artisan queue:work sqs --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=workerUserName
numprocs=8
redirect_stderr=true
stdout_logfile=/var/log/laravel-worker.log
stopwaitsecs=3600

# 定義 supervisor user default umask

在 worker ini 中:

umask=007

然後 reread & update

# 啟動

sudo systemctl start supervisord
sudo systemctl status supervisord

# 開機自動啟動

sudo systemctl enable supervisord

# 操作指令

sudo supervisorctl reread // 重讀但不重啟
sudo supervisorctl update // 重讀, 並且如果 config 有變更才重啟有變更的 process
sudo supervisorctl relaod // 重讀, 不管有無變更都會重啟所有 process
sudo supervisorctl restart // 只重啟, 不重讀

# APC cache

# Centos

sudo yum install php-pecl-apcu

# macOS

pecl install apcu

# 時區設定

# MySQL 時區

# 檢查 MySQL 時區

SELECT @@global.time_zone, @@session.time_zone;

# Server 時區

# 取得 server 時區

date +%Z

# 取得 server 可用時區

sudo timedatectl list-timezones

# 設定 server 時區

sudo timedatectl set-timezone Asia/Taipei

# 設定 Laravel 時區

修改 config/app.php 中的 timezone


# 記憶體不足

# 可劃分磁碟為替代記憶體

sudo dd if=/dev/zero of=/swapfile bs=1M count=2000;
sudo chmod 600 /swapfile;
sudo mkswap /swapfile;
sudo swapon /swapfile;
swapon -s;
sudo vim /etc/fstab;
/swapfile swap swap defaults 0 0

# 若使用 GCP, 要讓 MySQL 可從外部存取

# 開權限

LOCAL_IP=$(curl  http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip \
-H "Metadata-Flavor: Google")
sudo sed -i "s|bind-address.*|bind-address = $LOCAL_IP|" /etc/mysql/mysql.conf.d/mysqld.cnf

更多設定可參考官方文件


# lsb-release

# 安裝

sudo apt-get install lsb-release

# 用法

lsb_release --help
-h, --help         show this help message and exit
-v, --version show LSB modules this system supports
-i, --id show distributor ID
-d, --description show description of this distribution
-r, --release show release number of this distribution
-c, --codename show code name of this distribution
-a, --all show all of the above information
-s, --short show requested information in short format

# 查詢細節

lsb_release -a

# 只顯示 kernel 版本

uname -r

## # server optimization ### # sysctl - 到 `/etc/sysctl.d/` 下建立 custom.conf - 加入以下設定
net.core.somaxconn=10000
net.ipv4.ip_local_port_range=10000 65535
net.ipv4.tcp_tw_reuse=1
  • reload, sysctl --system
怎麼在 Laravel 中, 利用 AWS SES 發郵件? Laravel - Packages - Fortify

留言

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×