Laravel 个人服务器环境搭建部署

Ubuntu 18.04

你需要向运营商购买一台 Ubuntu 18.04 版本的vps,或者你拥有自己的机器,在此不表。
以下为 初始化系统

刷新软件源

[root@Ubuntu:~]# apt update
Get:1 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
Hit:2 http://archive.ubuntu.com/ubuntu bionic InRelease   
Get:3 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]       ...
Get:28 http://archive.ubuntu.com/ubuntu bionic-backports/universe amd64 Packages [4,028 B]
Get:29 http://archive.ubuntu.com/ubuntu bionic-backports/universe i386 Packages [4,028 B]
Fetched 7,335 kB in 3s (2,825 kB/s)             
Reading package lists... Done
Building dependency tree       
Reading state information... Done
39 packages can be upgraded. Run 'apt list --upgradable' to see them.
在这个过程中,包管理器(也就是 APT)将会从 软件源 服务器上获取一份最新的包列表并建立本地缓存,包括软件名称、描述、最新版本、下载地址等等。

稍等片刻即可刷新完毕,最后有可能提示:

39 packages can be upgraded. Run 'apt list --upgradable' to see them.

意为有 186 个软件包可升级,执行 apt list --upgradable 命令来查看它们。

我们暂且忽略,直接升级:

[root@Ubuntu:~]# apt upgrade
注意:生产环境下,更新任何软件包前都需要仔细检查,确保更新日志内没有影响现有环境的改动。另外,你也可以先不升级,对后续部署基本没有影响。

将会看到很多输出,它们是将被升级的软件列表;注意关注最后几行:

Reading package lists... Done
Building dependency tree       
Reading state information... Done
Calculating upgrade... Done
The following NEW packages will be installed:
  linux-headers-4.15.0-88 linux-headers-4.15.0-88-generic linux-image-4.15.0-88-generic
  ...
39 upgraded, 5 newly installed, 0 to remove and 0 not upgraded.
Need to get 74.6 MB of archives.
After this operation, 332 MB of additional disk space will be used.
Do you want to continue? [Y/n]

意为此操作将占用 332 MB 磁盘空间。此时输入 Y(注意关闭中文输入法),或直接回车即可开始升级。主流云服务厂商均有缓存软件源,数据流量是通过内网传输,所以该过程不会太慢。

#### 本地化配置

可理解为系统时区、单位、地址、语言等配置的统称。使其能够符合某一地区的习惯。虽然我们的母语是中文,但还是建议将服务器配置为英语,尽可能避免奇葩乱码等问题带来的影响。

首先,执行以下命令生成美国本地化数据:

[root@Ubuntu:~]# locale-gen en_US.UTF-8
Generating locales (this might take a while)...
  en_US.UTF-8... done
Generation complete.

随后将本地化配置修改为 en_US.UTF-8 即可:

[root@Ubuntu:~]# update-locale LC_ALL=en_US.UTF-8

如果服务器在国外,则服务商可能不会将其配置为东八区;我们还需手动修改时区为 Asia/Shanghai

[root@Ubuntu:~]# timedatectl set-timezone Asia/Shanghai

Nginx

#### 安装Nginx

由于我们执行 apt update 更新软件源不久,所以直接安装 Nginx 即可:

[root@Ubuntu:~]# apt install nginx
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages were automatically installed and are no longer required:
  linux-headers-4.15.0-55 linux-headers-4.15.0-55-generic linux-image-4.15.0-55-generic
  ...
Suggested packages:
  libgd-tools fcgiwrap nginx-doc ssl-cert
The following NEW packages will be installed:
  ...
0 upgraded, 18 newly installed, 0 to remove and 0 not upgraded.
Need to get 2,461 kB of archives.
After this operation, 8,210 kB of additional disk space will be used.
Do you want to continue? [Y/n] 

再次收到确认提示:

0 upgraded, 18 newly installed, 0 to remove and 0 not upgraded.
Need to get 2,461 kB of archives.
After this operation, 8,210 kB of additional disk space will be used.
Do you want to continue? [Y/n] 

输入Y或者直接回车即可

更新软件源已经包管理器从软件源服务器拉取软件包列表并建立本地缓存。当我们执行 apt install 操作时,包管理器便会从本地缓存中找到该软件包的指定版本,并进行下载、安装。

管理Nginx服务

我们可使用 service 命令管理服务状态,常用操作如下:

[root@Ubuntu:~]# service nginx start # 启动 Nginx
[root@Ubuntu:~]# service nginx stop # 停止 Nginx
[root@Ubuntu:~]# service nginx restart # 重启 Nginx

同时,可使用 systemctl 命令开关服务的开机自启:

[root@Ubuntu:~]# systemctl enable nginx # 启用 Nginx 开机启动
[root@Ubuntu:~]# systemctl disable nginx # 禁用 Nginx 开机启动
通常情况下,在 APT 安装后已默认启用 Nginx 开机启动。

确认 Nginx 正常运行

在浏览器内输入服务器公网 IP(或域名)并打开,出现默认欢迎页面说明 Nginx 已经正常运行
恭喜,Nginx 安装成功。

PHP 7.2

配置第三方软件源

由于 Ubuntu 的官方软件源通常不包含最新版本的 PHP,因此需要添加一个包含最新 PHP 的第三方软件源。

在添加之前,我们首先安装名为 software-properties-common 的软件包,它提供了快速管理软件源的实用脚本:

[root@Ubuntu:~]# apt install -y software-properties-common
Reading package lists... Done
Building dependency tree       
Reading state information... Done
software-properties-common is already the newest version (0.96.24.32.12).
The following packages were automatically installed and are no longer required:
  linux-headers-4.15.0-55 linux-headers-4.15.0-55-generic linux-image-4.15.0-55-generic
  linux-modules-4.15.0-55-generic linux-modules-extra-4.15.0-55-generic
Use 'apt autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
apt install 添加了 -y 选项,表示当 APT 遇到询问时默认确认,避免再次输入 Y 并回车。

随后,执行以下脚本添加第三方 PHP 软件源:

[root@Ubuntu:~]# add-apt-repository -y ppa:ondrej/php
Get:1 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
Hit:2 http://archive.ubuntu.com/ubuntu bionic InRelease                         ...
Fetched 402 kB in 1s (278 kB/s)                     
Reading package lists... Done

成功后别忘记刷新 apt 源:

[root@Ubuntu:~]# apt-get update
Get:1 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
Hit:2 http://archive.ubuntu.com/ubuntu bionic InRelease                                            
Get:3 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]                          
Hit:4 http://ppa.launchpad.net/ondrej/php/ubuntu bionic InRelease                                  
Get:5 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB]                        
Fetched 252 kB in 1s (352 kB/s)                               
Reading package lists... Done

安装PHP

PHP 的安装实际上分为三个软件包:

apt install 支持多参数,所以我们不必执行多次安装,只需在单条命令内写明多个软件包即可:

[root@Ubuntu:~]# apt install -y php7.2 php7.2-cli php7.2-fpm
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages were automatically installed and are no longer required:
  ...
Creating config file /etc/php/7.2/fpm/php.ini with new version
/php7.2-fpm.service.
Setting up php7.2 (7.2.27-6+ubuntu18.04.1+deb.sury.org+1) ...
Processing triggers for systemd (237-3ubuntu10.39) ...
...
Processing triggers for php7.2-fpm (7.2.27-6+ubuntu18.04.1+deb.sury.org+1) ...#############.....] 
Progress: [ 98%] [############################################################################..] 

按照 Laravel 5.8 安装文档 的说明,接着安装几个必备的 PHP 扩展:

[root@Ubuntu:~]# apt install -y php7.2-mbstring php7.2-xml php7.2-bcmath
注意:由于 PDO 等扩展已经内置在 PHP 中,故无需额外安装。

对于不同项目的不同依赖,可能有必要安装以下扩展,根据实际情况选择即可:

[root@Ubuntu:~]# apt install php7.2-curl php7.2-gd php7.2-mysql php7.2-opcache php7.2-zip php7.2-sqlite3

有个小技巧是,可以通过 apt-cache 命令来搜索当前软件源内的包:

[root@Ubuntu:~]# apt-cache search php7.2

例如以上命令,将会得到所有名称、描述等信息内包含 php7.2 字样的软件包:

libapache2-mod-php7.2 - server-side, HTML-embedded scripting language (Apache 2 module)
php7.2 - server-side, HTML-embedded scripting language (metapackage)
php7.2-cgi - server-side, HTML-embedded scripting language (CGI binary)
php7.2-cli - command-line interpreter for the PHP scripting language
...

管理 PHP-FPM 服务

与管理 Nginx 服务类似,同样可以通过 servicesystemctl 命令管理 PHP-FPM 服务:

[root@Ubuntu:~]# service php7.2-fpm restart # 重启 PHP-FPM
[root@Ubuntu:~]# service php7.2-fpm start # 启动 PHP-FPM
[root@Ubuntu:~]# service php7.2-fpm stop # 停止 PHP-FPM
[root@Ubuntu:~]# systemctl enable php7.2-fpm # 启用 PHP-FPM 开机启动
[root@Ubuntu:~]# systemctl disable php7.2-fpm # 禁用 PHP-FPM 开机启动
注意:不同版本的 PHP-FPM 服务名是不一致的。例如 7.2 为 php7.2-fpm,7.3 为 php7.3-fpm,以此类推……

确认 PHP-FPM 正常运行

通过以下命令可确认 PHP-FPM 进程正在运行:

[root@Ubuntu:~]# ps aux | grep php

其中:

ps 将进程信息输出到 grep 进行过滤,后者筛选出包含 php 字样的行,再将它们输出。于是,它们相结合,产生的效果便是这样:

root       619  0.0  1.7 452796  8684 ?        Ss   Feb23   0:08 php-fpm: master process (/etc/php/7.2/fpm/php-fpm.conf)
www-data   717  0.1  6.6 459756 32736 ?        S    Feb23   2:24 php-fpm: pool www
www-data  1345  0.1  6.7 459904 33236 ?        S    Feb23   2:21 php-fpm: pool www
www-data  1571  0.1  6.9 459736 34156 ?        S    Feb23   2:18 php-fpm: pool www
root      8494  0.0  0.1  14728   920 pts/0    S+   15:31   0:00 grep --color=auto php

忽略最后一行(这是我们正在执行的 grep 命令),可观察到有 php-fpm 进程正在运行中。

若 PHP-FPM 进程不存在,那么输出将只有孤零零的 grep

root      8494  0.0  0.1  14728   920 pts/0    S+   15:31   0:00 grep --color=auto php
提示:你可以结合上文提到的 service 命令,将服务进程手动停止试试看;测试完毕不要忘记再次启动。

Mysql 5.7.22

安装

[root@Ubuntu:~]# apt install mysql-server mysql-client mysql-common

设置使用

创建新用户
[root@Ubuntu:kangxuanpeng.com]# mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.29-0ubuntu0.18.04.1 (Ubuntu)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
mysql> create user 'kangxuanpeng'@'127.0.0.1' identified by 'passwd';
Query OK, 0 rows affected (0.01 sec)
创建数据库
mysql> CREATE DATABASE  `kangxuanpeng` DEFAULT CHARACTER SET utf8mb4 -- UTF-8 Unicode COLLATE utf8mb4_general_ci;
授权
mysql> grant all on kangxuanpeng.* to 'kangxuanpeng'@'127.0.0.1';
Query OK, 0 rows affected, 1 warning (0.01 sec)
可以用新用户尝试登录操作 database

Git 和 Composer

Git 和 Composer 是部署 PHP 项目时必不可少的两款工具。用它们代替原有 SCP 方案有许多好处:

安装 Git

依然使用 APT 安装:

[root@Ubuntu:~]# apt install -y git
Reading package lists... Done
Building dependency tree       
Reading state information... Done
git is already the newest version (1:2.17.1-1ubuntu0.5).
The following packages were automatically installed and are no longer required:
  linux-headers-4.15.0-55 linux-headers-4.15.0-55-generic linux-image-4.15.0-55-generic
  linux-modules-4.15.0-55-generic linux-modules-extra-4.15.0-55-generic
Use 'apt autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 6 not upgraded.

安装 Composer

Composer 比较特殊,不能通过 APT 安装。虽然网络上流传着一大堆从第三方服务器直接下载 composer.phar 文件的安装方式,但根据 Composer 的官方文档,正确的安装姿势应当为:

[root@Ubuntu:~]# wget https://raw.githubusercontent.com/composer/getcomposer.org/master/web/installer -O - -q | php -- --filename=composer --install-dir=/usr/local/bin
以上修改自 https://getcomposer.org/doc/faqs/how-to-install-composer-programmatically.md>,另一种比较复杂的安装方式可参考 。你可以不必关心该脚本的具体意义,通常它只需执行一次。

注意:通过第三方服务器、直接下载 composer.phar 不进行任何检查,均无法保证 Composer 正常运行,且存在安全风险!请务必遵循官方文档内的说明。

稍等片刻,将会出现以下输出:

All settings correct for using Composer
Downloading...

提示当前环境检查通过,可正常使用 Composer;随后开始下载。

鉴于众所周知的原因,大陆访问国际网络速度奇慢无比,请耐心等待。当出现以下提示时,表示已经安装成功:

Composer (version 1.9.3) successfully installed to: /usr/local/bin/composer
Use it: php /usr/local/bin/composer

按照提示,我们可以使用 /usr/local/bin/composer 运行 Composer,当然,还有个更简单的方法:

[root@Ubuntu:~]# composer
Do not run Composer as root/super user! See https://getcomposer.org/root for details
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.9.3 2020-02-04 12:58:49

Usage:
  command [options] [arguments]

Options:
  -h, --help                     Display this help message
  -q, --quiet                    Do not output any message
  ...

配置 Packagist 中国镜像

这一步是可选的。如果你的服务器位于大陆,强烈建议使用可信赖的代理,或是国内 Packagist 镜像。

推荐使用阿里云提供的 Packagist 中国镜像,执行以下命令即可切换服务器内 Composer 的默认 Packagist 源:

[root@Ubuntu:~]# composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

代码部署

首次部署

配置 Nginx 站点

根据 Laravel 5.8 部署文档 的说明,我们可直接拿到一份现成的 Nginx 配置文件,稍作调整即可:

server {
    listen 80;
    server_name kangxuanpeng.com; # 此为必修改项,请替换为服务器公网 IP 或域名
    root /var/www/kangxuanpeng.com/public; # 此为必修改项,请注意指向站点根目录的 public 子目录

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.html index.htm index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; # 请注意核对 PHP 版本
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}
提示:关于以上 Nginx 配置项的解析,可参见 这篇博客

通常我们仅需修改 server_namerootfastcgi_pass;请注意阅读 # 后的注释。

将以上内容保存到 kangxuanpeng.com.conf内,移动到 /etc/nginx/sites-enabled/ 目录

重载 Nginx

配置完成后,请务必重启(Restart)或重载(Reload)Nginx。

什么是 重载?实际上,直接重启 Nginx 是不安全的。原因有二:

在之前的小节中,已经提到重启 Nginx 的方法;

[root@Ubuntu:~]# service nginx restart

同样地,亦可使用 service 命令重载 Nginx:

[root@Ubuntu:~]# service nginx reload

另一种等效的方法是:

[root@Ubuntu:~]# nginx -s reload
Laravel 生成应用 Key
[root@Ubuntu:~]# php artisan key:generate
将应用的 key(APP_KEY)设置为一个随机32位的字符串。如果应用 key 没有设置,用户 Session 和其它加密数据将会有安全隐患!
设置生产环境,关闭调试模式
[root@kangxuanpeng.com:~]# vim .env

修改为

APP_ENV=production
APP_DEBUG=false
自动加载器改进

当你准备往生产环境部署应用时,确保你优化了你的 Composer 类的自动加载映射,这样可以使 Composer 可以很快的找到正确的加载文件去加载给定的类:

composer install --optimize-autoloader --no-dev
小提示:除了优化自动加载器,你还应该确保在你的项目代码仓库中包含了 composer.lock 这个文件。当你的项目代码中有 composer.lock 这个文件时,便可以更快的安装项目中需要的依赖项。
优化配置加载

当你将应用程序部署到生产环境时,你应当确保在你部署过程中运行 config:cache Artisan 命令:

php artisan config:cache

此命令将所有 Laravel 的配置文件合并到一个缓存文件,这将极大地减少框架在加载配置值时必须对文件系统进行访问的次数。

注意:如果在你部署过程中执行 config:cache 命令,你应当确保你仅从你的配置文件中调用 env 函数。一旦配置被缓存,.env 文件将不被加载并且对 env 函数的所有调用将返回 null。
优化路由加载

如果你想构建具有许多路由的大型应用程序,你应当确保在你部署的过程中运行 route:cache Artisan 命令:

php artisan route:cache

此命令将为所有路由注册缩减到一个缓存文件中的单个方法调用,从而在注册数百个路由时提高了路由注册的性能。

注意:由于此功能使用 PHP 序列化,你仅能缓存专门使用基于控制器路由的应用程序路由。PHP 不能序列化闭包路由。
设置文件目录权限
[root@Ubuntu:wwwroot]# chmod -R 755 kangxuanpeng.com/
[root@Ubuntu:wwwroot]# chown -R www-data kangxuanpeng.com/

版本更新

备份相关备份

在此不表

维护模式
php artisan down

即使在维护模式下,也可以通过 allow 选项指定 IP 地址或网络来访问应用:

php artisan down --allow=127.0.0.1 --allow=192.168.0.0/16
更新代码及数据库
git pull
php artisan migrate
各种清空缓存和重建缓存
php artisan clear-compiled
php artisan cache:clear
php artisan config:cache
php artisan optimize
composer install --optimize-autoloader --no-dev
composer dump-autoload --optimize
关闭维护状态,更新完毕
php artisan up

安全相关

安全强化 SSH

Linux 创建用户账号代替 root 账号,避免使用永久性 root 权限帐号登陆

启用防火墙

现在,你需要安装防火墙、启用防火墙并对其进行配置,以仅允许你指定的网络流量通过。(Ubuntu 上的)简单的防火墙(UFW)是一个易用的 iptables 界面,可大大简化防火墙的配置过程。

你可以通过以下方式安装 UFW(root用户):

[root@Ubuntu:~]# apt install ufw
Reading package lists... Done
Building dependency tree       
Reading state information... Done
ufw is already the newest version (0.36-0ubuntu0.18.04.1).
The following packages were automatically installed and are no longer required:
  linux-headers-4.15.0-55 linux-headers-4.15.0-55-generic linux-image-4.15.0-55-generic
  linux-modules-4.15.0-55-generic linux-modules-extra-4.15.0-55-generic
Use 'sudo apt autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 6 not upgraded.

默认情况下,UFW 拒绝所有传入连接,并允许所有传出连接。这意味着服务器上的任何应用程序都可以访问互联网,但是任何尝试访问服务器的内容都无法连接。

首先,确保你可以通过启用对 SSH、HTTP 和 HTTPS 的访问来登录:

[root@Ubuntu:~]# ufw allow ssh
[root@Ubuntu:~]# ufw allow http
[root@Ubuntu:~]# ufw allow https

然后启用 UFW:

[root@Ubuntu:~]# ufw enable

你可以通过以下方式查看允许和拒绝了哪些服务:

[root@Ubuntu:~]# ufw status
Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere                  
80/tcp                     ALLOW       Anywhere                  
443/tcp                    ALLOW       Anywhere                  
22/tcp (v6)                ALLOW       Anywhere (v6)             
80/tcp (v6)                ALLOW       Anywhere (v6)             
443/tcp (v6)               ALLOW       Anywhere (v6)             

如果你想禁用 UFW,可以通过键入以下命令来禁用:

[root@Ubuntu:~]# ufw disable

你还可以(在 RHEL/CentOS 上)使用 firewall-cmd,它已经安装并集成到某些发行版中。

安装 Fail2ban

Fail2ban 是一种用于检查服务器日志以查找重复或自动攻击的应用程序。如果找到任何攻击,它会更改防火墙以永久地或在指定的时间内阻止攻击者的 IP 地址。

你可以通过键入以下命令来安装 Fail2ban:

[root@Ubuntu:~]# apt install fail2ban -y

然后复制随附的配置文件:

[root@Ubuntu:~]# cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

重启 Fail2ban:

[root@Ubuntu:~]# service fail2ban restart

这样就行了。该软件将不断检查日志文件以查找攻击。一段时间后,该应用程序将建立相当多的封禁的 IP 地址列表。你可以通过以下方法查询 SSH 服务的当前状态来查看此列表:

[root@Ubuntu:~]# fail2ban-client status sshd

移除无用的网络服务

几乎所有 Linux 服务器操作系统都启用了一些面向网络的服务。你可能希望保留其中大多数,然而,有一些你或许希望删除。你可以使用 ss 命令查看所有正在运行的网络服务:(LCTT 译注:应该是只保留少部分,而所有确认无关的、无用的服务都应该停用或删除。)

[root@Ubuntu:~]# ss -atpu

ss 的输出取决于你的操作系统。下面是一个示例,它显示 SSH(sshd)和 Ngnix(nginx)服务正在侦听网络并准备连接:

tcp LISTEN 0 128 *:http *:* users:(("nginx",pid=22563,fd=7))
tcp LISTEN 0 128 *:ssh *:* users:(("sshd",pid=685,fd=3))

删除未使用的服务的方式因你的操作系统及其使用的程序包管理器而异。

要在 Debian / Ubuntu 上删除未使用的服务:

[root@Ubuntu:~]# apt purge <service_name>

要在 Red Hat/CentOS 上删除未使用的服务:

[root@Centos:~]# yum remove <service_name>

再次运行 ss -atup 以确认这些未使用的服务没有安装和运行。

检查网络监听的端口。

使用 netstat 命令查看服务器中有哪些监听端口

[root@Ubuntu:~]# netstat -tulpn

如果有不需要的服务,可以使用 chkconfig 进行关闭。如果需要对外屏蔽,可以使用 iptables 。

禁用IPV6

Ubuntu 禁用IPv6的方法

资料参考

Responses
  1. joeMxbwXuSci

    Reply
  2. GIPDrpaOiwmvAWx

    Reply