怎样在 Laravel 中使用 Vultr 对象存储

介绍

Laravel 具有强大的文件存储抽象,可以与多种类型的文件系统进行交互。 它支持 S3 兼容的云存储,如 Vultr 对象存储来存储静态文件。

本指南解释了怎样为 Vultr 对象存储配置 Laravel 文件存储系统,并使用它来存储用户从 Web 门户上传的文件。

先决条件

在开始之前,您应该:

安装 Nginx 和 PHP

添加 翁德雷 存储库以获取最新版本的 Nginx 和 PHP。

$ sudo add-apt-repository -y ppa:ondrej/php

$ sudo add-apt-repository -y ppa:ondrej/nginx-mainline

$ sudo apt update

安装 Nginx。

$ sudo apt install nginx

安装 PHP 及其扩展。

$ sudo apt install php-{cli,fpm,mysql,gd,soap,mbstring,bcmath,common,xml,curl,imagick,zip}

安装作曲家。

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

$ php composer-setup.php

$ php -r "unlink('composer-setup.php');"

$ sudo mv composer.phar /usr/local/bin/composer

配置 PHP

  1. 为 PHP FastCGI 进程管理器 (PHP-FPM) 池创建一个新用户。 该用户运行 PHP-FPM 进程并拥有网站文件所有权。 它为您的网站增加了额外的安全性和隔离性。

    $ sudo adduser website
    
    $ sudo usermod -a -G website www-data
    
  2. 创建网站目录。

    $ sudo mkdir /var/www/website
    
  3. 更改目录所有权。

    $ sudo chown website:website /var/www/website
    
  4. 复制默认 PHP-FPM 池配置作为新池的模板。

    $ sudo cp /etc/php/8.1/fpm/pool.d/www.conf /etc/php/8.1/fpm/pool.d/website.conf
    
  5. 打开池配置文件。

    $ sudo nano /etc/php/8.1/fpm/pool.d/website.conf
    

    添加以下更改。

    • 更改池名称 [www][website].

    • 换行 user = www-datauser = website.

    • 换行 group = www-datagroup = website.

    • 换行 listen = /run/php/php8.1-fpm.socklisten = /run/php/php8.1-fpm-website.sock.

    Save 文件并退出。

  6. 打开 php.ini 文件。

    $ sudo nano /etc/php/8.1/fpm/php.ini
    

    通过更改增加 PHP 最大上传文件大小 upload_max_filesize = 2Mupload_max_filesize = 10Mpost_max_size = 8Mpost_max_size = 10M.

  7. 删除默认的 PHP-FPM 池配置。

    $ sudo rm /etc/php/8.1/fpm/pool.d/www.conf
    
  8. 重新启动 PHP-FPM。

    $ sudo systemctl restart php8.1-fpm
    

配置 Nginx

  1. 禁用默认的 Nginx 配置。

    $ sudo unlink /etc/nginx/sites-enabled/default
    
  2. 创建一个新的 Nginx 配置文件。

    $ sudo nano /etc/nginx/sites-available/website
    
  3. 添加以下配置。

    server {
    
        listen 80;
    
        listen [::]:80;
    
    
    
        server_name example.com;
    
    
    
        root /var/www/website/public;
    
    
    
        index index.html index.htm index.php;
    
    
    
        charset utf-8;
    
    
    
        client_max_body_size 10m;
    
        client_body_timeout 60s;
    
    
    
        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; }
    
    
    
        access_log /var/log/example.com-access.log;
    
        error_log  /var/log/example.com-error.log error;
    
    
    
        error_page 404 /index.php;
    
    
    
        location ~ .php$ {
    
            include snippets/fastcgi-php.conf;
    
            fastcgi_pass unix:/run/php/php8.1-fpm-website.sock;
    
            fastcgi_buffers 32 32k;
    
            fastcgi_buffer_size 32k;
    
        }
    
    }
    

    确保更改域名 example.com 到您的域。 Save 文件并退出。

  4. 启用 Nginx 配置。

    $ sudo ln -s /etc/nginx/sites-available/website /etc/nginx/sites-enabled/
    
  5. 在防火墙中允许 Nginx。

    $ sudo ufw allow 'Nginx Full'
    
  6. 重启 Nginx。

    $ sudo systemctl restart nginx
    

安装 Node.js

Laravel 需要 Node.js 来编译它的前端资产。 使用 Snap 包管理器安装最新的 Node.js 版本。

$ sudo snap install core

$ sudo snap refresh core

$ sudo snap install --classic node

创建对象存储

  1. 登录到 Vultr 客户门户.

  2. 导航 产品 -> 对象.

  3. 添加对象存储 并给它一个标签。

  4. 单击您的对象存储并导航到存储桶选项卡。

  5. 创建一个 Bucket 并为其命名。

  6. 注意 主机名, 这 密钥, 这 访问密钥存储桶名称.

创建门户网站

对于剩余的任务,您需要使用 website 用户。 通过运行以下命令更改用户。

$ sudo su website

创建新的 Laravel 项目

转到网站目录。

$ cd /var/www/website

使用 Composer 创建一个新的 Laravel 项目。

$ composer create-project laravel/laravel .

配置 Laravel 文件系统

Laravel 文件存储有一个 S3 驱动程序来与 S3 兼容的云存储(如 Vultr 对象存储)进行交互。 它需要 Flysystem S3 软件包。 通过 Composer 包管理器安装它。

$ composer require league/flysystem-aws-s3-v3 "^3.0"

打开 .env 文件。

$ nano .env

更改 FILESYSTEM_DISKs3. 它告诉 Laravel 文件存储使用 S3 驱动程序。

FILESYSTEM_DISK=s3

将 Vultr 对象存储凭据添加到环境变量。

AWS_ENDPOINT=https://sgp1.vultrobjects.com

AWS_ACCESS_KEY_ID=1234567890ABCDEFGH

AWS_SECRET_ACCESS_KEY=ABCDEFGHIJKLMNOPQ

AWS_BUCKET=example

凭证说明:

  • AWS_ENDPOINT 是您的 Vultr 对象存储主机名。

  • AWS_ACCESS_KEY_ID 是您的 Vultr 对象存储访问密钥。

  • AWS_SECRET_ACCESS_KEY 是您的 Vultr 对象存储密钥。

  • AWS_BUCKET 是您的 Vultr 对象存储桶名称。

添加顺风 CSS

本指南使用 Tailwind CSS 作为 CSS 框架。 通过 NPM 安装它。

$ npm install -D tailwindcss postcss autoprefixer

创建并打开 Tailwind CSS 配置文件。

$ npx tailwindcss init -p

$ nano tailwind.config.js

将内容更改为:

/** @type {import('tailwindcss').Config} */

module.exports = {

  content: [

    "./resources/**/*.blade.php",

    "./resources/**/*.js",

  ],

  theme: {

    extend: {},

  },

  plugins: [],

}

打开 resources/css/app.css 文件并添加 Tailwind CSS 指令。

@tailwind base;

@tailwind components;

@tailwind utilities;

添加 JavaScript

打开 resources/js/app.js 文件并添加以下代码:

document.getElementById('fileImage').addEventListener('change',function(){

    if( this.files.length > 0 ){

        document.getElementById('uploadBtn').removeAttribute('disabled');

    }

});

创建视图

创造 resources/views/gallery.blade.php 具有以下内容的文件:

<html>

    <head>

        <title>Gallery</title>



        @vite(['resources/css/app.css', 'resources/js/app.js'])

    </head>

    <body>

        <div class="max-w-7xl m-auto">

            <h1 class="text-3xl font-bold text-gray-900 text-center py-8 uppercase">Gallery</h1>

            <form action="" method="post" enctype="multipart/form-data" class="flex flex-wrap text-center items-center justify-center p-4 rounded-lg items-center">

                @csrf

                <label class="block">

                  <input id="fileImage" type="file" name="fileImage" class="block w-full text-sm text-slate-500 pr-6

                    file:cursor-pointer

                    file:mr-4 file:py-2 file:px-4

                    file:rounded-full file:border-0

                    file:text-sm file:font-semibold

                    file:bg-indigo-50 file:text-indigo-700

                    hover:file:bg-indigo-100

                  "/>

                  @if ($errors->has('fileImage'))

                    <span class="block text-red-700 py-4 text-left">{{ $errors->first('fileImage') }}</span>

                  @endif

                </label>

                <button id="uploadBtn" disabled class="rounded border border-transparent bg-indigo-600 px-6 py-2 text-base font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 disabled:opacity-50" type="submit">

                    Upload Image

                </button>

            </form>



            <div class="grid grid-cols-2 gap-x-4 gap-y-8 sm:grid-cols-3 sm:gap-x-6 lg:grid-cols-4 xl:gap-x-8">

                @foreach ($images as $image)

                    <div>

                        <img class="rounded" src="">

                    </div>

                @endforeach

            </div>

        </div>

    </body>

</html>

编译前端资产。

$ npm run build

创建控制器

创建一个 GalleryController.

$ php artisan make:controller GalleryController

打开 GalleryController 文件。

$ nano app/Http/Controllers/GalleryController.php

加载 Storage 在门面 GalleryController 文件。 它包含一组您需要与对象存储交互的功能。

use IlluminateSupportFacadesStorage;

创建 index 行动。 它显示上传表单并列出来自 gallery 存储桶中的文件夹。 它使用 files 方法从 Storage 外观以获取目录中所有文件的数组。

public function index()

{

    $images = Storage::files('gallery');

    return view('gallery', compact('images'));

}

创建 upload 行动。 它在用户上传他们的图像时进行处理。 它验证文件,然后使用 putFile 方法从 Storage 正面。

public function upload(Request $request)

{

    $validated = $request->validate([

        'fileImage' => 'required|image',

    ]);



    Storage::putFile('gallery', $validated['fileImage'], 'public');



    return redirect("https://www.vultr.com/");

}

以下是本次活动的全部内容 GalleryController 文件:

<?php



namespace AppHttpControllers;



use IlluminateHttpRequest;

use IlluminateSupportFacadesStorage;



class GalleryController extends Controller

{

    public function index()

    {

        $images = Storage::files('gallery');



        return view('gallery', compact('images'));

    }



    public function upload(Request $request)

    {

        $validated = $request->validate([

            'fileImage' => 'required|image',

        ]);



        Storage::putFile('gallery', $validated['fileImage'], 'public');



        return redirect("https://www.vultr.com/");

    }

}

定义路线

打开 routes/web.php.

$ nano routes/web.php

使用以下代码更新它:

<?php

use IlluminateSupportFacadesRoute;

use AppHttpControllersGalleryController;



Route::get("https://www.vultr.com/", [GalleryController::class, 'index']);

Route::post("https://www.vultr.com/", [GalleryController::class, 'upload']);

测试门户网站

  1. 在浏览器中打开您的域。

  2. 您应该会看到上传表单。

  3. 上传一张图片。

  4. 检查图像是否出现在您的 Vultr 对象存储 以及上传表单下方的图库。

使用 Let’s Encrypt 保护 Web 门户

Let’s Encrypt 为您的网站提供免费的 SSL 证书。 要生成证书,您需要使用 Certbot 软件工具。

  1. 安装 Certbot。

    $ sudo snap install core; sudo snap refresh core
    
    $ sudo snap install --classic certbot
    
    $ sudo ln -s /snap/bin/certbot /usr/bin/certbot
    
  2. 生成 SSL 证书。

    $ sudo certbot --nginx
    
  3. 在浏览器中访问您的域并确认它具有 HTTPS 连接。

Let’s Encrypt 证书在 90 天后过期。 Certbot 将续订命令添加到 systemd 计时器或 Cron Job 以在证书过期之前自动续订。 您可以使用以下命令对其进行验证:

$ systemctl list-timers | grep 'certbot|ACTIVATES'

$ ls -l /etc/cron.d/certbot

结论

Laravel 文件存储提供了与不同存储系统交互的单一接口。 它有一个 S3 驱动程序,可用于在 Laravel 中集成 Vultr 对象存储。

延伸阅读

  • Vultr 对象存储。

  • Laravel 文件存储.

  • 安装让我们加密。

文章标题 名称(可选) 电子邮件(可选) 描述

发送建议

注:本教程在Vultr VPS上测试通过,如需部署请前往Vultr.com