前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >初试云原生?用腾讯云Serverless(SCF)搭建Typecho博客

初试云原生?用腾讯云Serverless(SCF)搭建Typecho博客

原创
作者头像
用户8721977
发布2023-08-23 15:57:07
4041
发布2023-08-23 15:57:07
举报
文章被收录于专栏:庭院一角庭院一角

经历千辛万苦,我终于安置好了个人站。

开整前的胡扯

以前个人站在腾讯云的孟买轻量应用服务器上,访问速度感人。后来就将他合并进主站所在的北京应用服务器,但在国内的服务器提供网站服务都需要备案。个人站因为域名原因没法备案,所以大部分地区都会被屏蔽。后来我也动过租一个香港节点服务器的念头,但是看到恐怖的单价,我这个穷学生只得望而却步。

这可是起步价
这可是起步价

前几天和朋友聊到了ipfs,和他分享了imalan的静态博客生成器。闲聊之余,我也对Vercel的静态网站托管服务起了兴趣。在简单了解后我得知Vercel可以托管PHP网站,便尝试将自己的typecho博客部署上去。然而在构建时生成的api.php超过了最大限制(50MB),我也只好作罢……

当然不可能。Vercel勾起了我对Serverless的好奇。经过一番研究后,我选择在腾讯云的SCF部署一个Typecho博客。

开整准备

  1. typecho本体(目前最新版本为1.2.1,经体验似乎没出现与1.2.0插件/主题不兼容的情况)
  2. Apache/Nginx(十分建议,不过非必选,用于在本地进行修改后的预览以及功能测试)

开整

部署前的准备

首先在腾讯云新建一个TDSQL-C数据库。建立数据库的详细教程不再给出,这里仅记录本例子的配置。实例形态选择Serverless,地域选择自己之后准备部署博客的地域(这里以广州为例),新建一个私有网络或使用默认,数据库版本选择MySQL8.0。算力配置和自动暂停用默认配置,默认字符集为UTF8MB4,表名大小写不敏感。

创建完成后进入集群详情,开启外网地址。

登录刚才创建的数据库,新建一个数据库,字符集使用utf8mb4,名称随意,如图本示例使用“example”。

新建数据库
新建数据库

如果你的typecho是从其他服务器迁移的(根目录下有config.inc.php),则可跳过第一次运行生成config.inc.php的步骤,直接转到创建scf_boostrap处。

将获得的Typecho本体部署到本地的Apache或Nginx上,进行第一次运行。关于如何将Typecho部署在web服务器上,网上教程漫天飞,本文不再赘述。

在第一次部署后,访问localhost会自动跳转到install.php,引导用户进行初始化。

初始化配置阶段,我们要将刚刚新建的数据库地址,端口(在高级选项里),数据库名,用户名和密码填进去。数据库适配器选择Pdo驱动Mysql适配器,数据库前缀自行设置,这里展示本例子的配置。

配置数据库
配置数据库

然后设置管理员账户后,typecho的初次设置就完成了,此时访问localhost,则会正常进入首页如图。

平平无奇的主页
平平无奇的主页

此时再检查typecho的项目结构,会发现根目录下多了一个文件:config.inc.php。打开该文件,可以看到刚才的配置信息都已记录到该文件中,此处展示本示例的config.inc.php

代码语言:php
复制
<?php
// site root path
define('__TYPECHO_ROOT_DIR__', dirname(__FILE__));

// plugin directory (relative path)
define('__TYPECHO_PLUGIN_DIR__', '/usr/plugins');

// theme directory (relative path)
define('__TYPECHO_THEME_DIR__', '/usr/themes');

// admin directory (relative path)
define('__TYPECHO_ADMIN_DIR__', '/admin/');

// register autoload
require_once __TYPECHO_ROOT_DIR__ . '/var/Typecho/Common.php';

// init
\Typecho\Common::init();

// config db
$db = new \Typecho\Db('Pdo_Mysql', 'typecho_');
$db->addServer(array (
  'host' => '***', //你的数据库地址
  'port' => 22957, //数据库端口
  'user' => 'root', //数据库用户名称
  'password' => '***', //数据库用户密码
  'charset' => 'utf8mb4', //数据库字符集
  'database' => 'example', //数据库名称
  'engine' => 'InnoDB',
  'sslCa' => '',
  'sslVerify' => true,
), \Typecho\Db::READ | \Typecho\Db::WRITE);
\Typecho\Db::set($db);

为了让他可以部署到SCF,我们要加入scf_bootstrap文件。这里先以SCF文档中展示的最简单的启动文件为例:

代码语言:txt
复制
#!/bin/bash
/var/lang/php7/bin/php -c /var/runtime/php7 -S 0.0.0.0:9000 index.php

这时的项目结构应如下:

代码语言:txt
复制
.
├─admin/
├─install/
├─usr/
├─var/
├─config.inc.php
├─index.php
├─install.php
├─LISENCE.txt
└─scf-boostrap

这样我们就做好了部署前的准备。

部署函数

进入serverless-函数服务,点击新建,选择“从头开始”。函数类型为Web函数,函数名称自己起。

地域选择与数据库相同的地域,运行环境为Php 7.4,时区为Asia/Shanghai(北京时间)。

将准备好的Typecho文件夹上传。这里展示本示例的配置。

选择国内地域的话,自定义域名需要备案
选择国内地域的话,自定义域名需要备案

进入高级配置,描述按自己喜好修改,启动命令不用管,腾讯云会优先使用项目文件中的scf_bootstrap文件。

内存初始化超时时间按自己需求修改,执行超时时间建议不要低于五秒。

在网络配置中启用私有网络,选择和数据库相同的私有网络和子网。

完成以上配置后点击完成,函数就会开始部署。部署完成后进入触发管理。点击“创建触发器”,点击提交,就可以得到公网的访问路径。点击后出现Typecho主页,初步配置就完成了。

设置数据库从内网访问

在上一步中的网络配置中正确设置了私有网路,那么我们就可以通过内网访问数据库,提升访问速度和安全性。

进入函数管理,点击函数代码,打开config.inc.php,修改其中有关数据库的内容。将数据库地址改为其内网地址,端口改为3306,其余内容不需要变动,点击部署即可。

config.inc.php
config.inc.php

部署成功后,点击下方的访问路径,可以正常访问,则表示配置成功,记得将数据库的外网地址关闭。

配置handler.php

此时我们点击Typecho主页的登录,会发现仍然会跳转到主页,无法正常访问后台。我们需要修改逻辑,使得可以访问其他PHP文件。

这里我们可以借鉴 Serverless Cloud Framework WordPress 组件,参考其handle.php的内容。以下直接给出解决步骤:

src目录下新建handle.php,并输入以下内容:

代码语言:txt
复制
<?php
error_reporting(0);

$extension_map = array(
    "css" => "text/css",
    "js" => "application/javascript",
    "png" => "image/png",
    "jpeg" => "image/jpeg",
    "jpg" => "application/x-jpg",
    "svg" => "image/svg+xml",
    "gif" => "image/gif",
    "pdf" => "application/pdf",
    "mp4" => "video/mpeg4",
    "bmp" => "application/x-bmp",
    "c4t" => "application/x-c4t",
    "img" => "application/x-img",
    "m2v" => "video/x-mpeg",
    "mp2v" => "video/mpeg",
    "mpeg" => "video/mpg",
    "ppt" => "application/x-ppt",
    "rm" => "application/vnd.rn-realmedia",
    "swf" => "video/mpeg4",
    "tif" => "image/tiff",
    "tiff" => "image/tiff",
    "ttf" => "application/x-font-ttf",
    "woff" => "application/x-font-woff",
    "vcf" => "text/x-vcard",
    "wav" => "audio/wav",
    "wma" => "audio/x-ms-wma",
    "wmv" => "video/x-ms-wmv",
    "apk" => "application/vnd.android.package-archive",
    "m1v" => "video/x-mpeg",
    "m3u" => "audio/mpegurl",
    "mp2" => "audio/mp2",
    "mp3" => "audio/mp3",
    "mpa" => "video/x-mpg",
    "mpe" => "video/x-mpeg",
    "mpg" => "video/mpg",
    "mpv2" => "video/mpeg",
    "rmvb" => "application/vnd.rn-realmedia-vbr",
    "torrent" => "application/x-bittorrent",
);

$request_uri = explode("?", $_SERVER['REQUEST_URI']);
$local_file_path = $_SERVER['DOCUMENT_ROOT'] . urldecode($request_uri[0]);
$remote_file_path = "/mnt/" . urldecode($request_uri[0]);


if ( $local_file_path == __FILE__ ) {
    http_response_code(400);
    echo 'Sorry';
    exit();
}


$db_mode = "";
$db_mode = getenv("DB_MODE");
$cdb_st = microtime(true);
$split = explode(".", $local_file_path);
$extension = end($split);
$mapped_type = $extension_map[$extension];

if ( $mapped_type && file_exists( $remote_file_path ) ) {

    header("Content-Type: {$mapped_type}");
    $file_size=filesize($remote_file_path);
    header("Accept-Length:$file_size");
    $fp=fopen($remote_file_path,"r");
    $buffer=1024;
    $file_count=0;
    while(!feof($fp)&&($file_size-$file_count>0)){
        $file_data=fread($fp,$buffer);
        $file_count+=$buffer;
        echo $file_data;
    }
    fclose($fp);
} elseif ( $mapped_type && file_exists( $local_file_path ) ) {

    header("Content-Type: {$mapped_type}");
    $file_size=filesize($local_file_path);
    header("Accept-Length:$file_size");
    $fp=fopen($local_file_path,"r");
    $buffer=1024;
    $file_count=0;
    while(!feof($fp)&&($file_size-$file_count>0)){
        $file_data=fread($fp,$buffer);
        $file_count+=$buffer;
        echo $file_data;
    }
    fclose($fp);

} elseif ( $extension == "php" && file_exists( $local_file_path ) ) {

    $cdb_et = microtime(true);
    $cdb_time = ($cdb_et - $cdb_st) * 1000 . 'ms';
    header("X-cdb-time:{$cdb_time}");
    header('Cache-Control:no-cache,must-revalidate');
    header('Pragma:no-cache');
    header("Expires:0");
    header("X-ExecFile: {$local_file_path}");
    require( $local_file_path );

} elseif ( substr($local_file_path, -1) == "/" && file_exists( $local_file_path . "index.php" ) ) {
    $cdb_et = microtime(true);
    $cdb_time = ($cdb_et - $cdb_st) * 1000 . 'ms';
    header("X-cdb-time:{$cdb_time}");
    header('Cache-Control:no-cache,must-revalidate');
    header('Pragma:no-cache');
    header("Expires:0");
    $exec_file_path = $local_file_path . "index.php";
    header("X-ExecFile: {$exec_file_path}");
    require( $exec_file_path );
} else {
    $cdb_et = microtime(true);
    $cdb_time = ($cdb_et - $cdb_st) * 1000 . 'ms';
    header("X-cdb-time:{$cdb_time}");
    header('Cache-Control:no-cache,must-revalidate');
    header('Pragma:no-cache');
    header("Expires:0");
    $exec_file_path = dirname(__FILE__) . '/index.php';
    header("X-ExecFile: {$exec_file_path}");
    require( $exec_file_path );
}

然后修改scf_bootstrap文件:

代码语言:txt
复制
#!/bin/bash
/var/lang/php7/bin/php -c /var/runtime/php7 -S 0.0.0.0:9000 handle.php

此时的项目结构应当如下:

代码语言:txt
复制
.
├─admin/
├─install/
├─usr/
├─var/
├─config.inc.php
├─handle.php
├─index.php
├─install.php
├─LISENCE.txt
└─scf-boostrap

完成后将其部署,就可以正常登录和访问后台了。

自定义域名

如果需要自定义域名,则需将触发器升级为API网关标准版。

进入触发管理,点击”升级至API网关标准版“。

如图,没啥好说的
如图,没啥好说的

点击你的API服务名,进入API网关控制台。进入自定义域名,将自己的域名进行配置,详细步骤不再展示。

补充内容

  1. 需要新增插件或主题时,只需将其上传到src/usr下的对应目录即可。
  2. 部署在SCF的Typecho将无法正常使用上传功能。这里给出两个方法解决:

一,将需要上传的图片/文件保存在图床,然后在博文中引用。

二,使用COS插件,填补博客的上传功能。我使用的是:腾讯云对象存储(COS)插件。设置时需关闭“在本地保存”功能。

整完后的胡扯

说实话,作为一介穷学生,以前几乎是没接触过云原生的,顶多用用docker。这次也算是摸到了云原生的一点边,确实是次十分新奇的体验。本文是咱第一次写这种技术教程,主要动机是“阿里云都有部署typecho的教程和模板,腾讯云居然一点内容都没有”,遂在折腾完后扯了这么一篇。没什么技术含量,甚至很多步骤都是“手把手”级别,希望能帮到其他初试serverless的人。如果本文有错漏或是可以改进之处,也希望得到各位大佬斧正,十分感谢。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 开整前的胡扯
  • 开整准备
  • 开整
    • 部署前的准备
      • 部署函数
        • 设置数据库从内网访问
          • 配置handler.php
            • 自定义域名
              • 补充内容
              • 整完后的胡扯
              相关产品与服务
              云函数
              云函数(Serverless Cloud Function,SCF)是腾讯云为企业和开发者们提供的无服务器执行环境,帮助您在无需购买和管理服务器的情况下运行代码。您只需使用平台支持的语言编写核心代码并设置代码运行的条件,即可在腾讯云基础设施上弹性、安全地运行代码。云函数是实时文件处理和数据处理等场景下理想的计算平台。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档