执行OOS快速部署静态网站至OSS

更新时间:2025-04-28 02:40:52

您可以通过OSS存储空间(Bucket)托管静态网站,并让访问者通过Bucket绑定的自定义域名(例如example.com)访问您的网站。当您的网站源代码存储在Git仓库(如GitHubGitee)时,请按照本文方法,创建OOS执行来快速部署静态网站到OSS。

准备工作

  • 注册网站域名

    搭建静态网站前,您需要为网站准备一个域名。建议您使用阿里云域名服务快速注册一个属于您的域名。具体操作,请参见通用域名注册基本流程如何注册阿里云域名

    本示例使用example.com作为测试域名。

    重要

    若您注册的域名需绑定在中国内地的Bucket上,您还需在中国工信部备案域名。更多信息,请参见备案

  • 创建Bucket

    创建一个Bucket(具有公共读权限),用以设置静态网站托管及存放网站数据。如果您未创建Bucket,请参见创建存储空间

  • 准备静态网站的网页文件

    您的Git仓库中应包含静态网站的源文件(例如index.htmlerror.html等文件),以下示例仅供参考:

    说明

    一个静态网站的页面包括index.htmlerror.html等文件,具体目录结构,请参见设置静态网站托管

    示例:在Git仓库上创建两个HTML格式文件(即默认首页和404错误页)

    • 默认首页

      本示例使用以下内容生成静态网站的首页文件index.html。实际环境中,请根据您的需求生成首页文件内容。

      <html>
         <head>
             <title>Hello OSS!</title>
             <meta charset="utf-8">
         </head>
         <body>
             <p>开始阿里云OSS托管</p>
             <p>这是索引页面</p>
         </body>
       </html>
    • 默认404页面

      本示例使用以下内容生成静态网站的404错误页文件error.html。实际环境中,请根据您的需求生成404错误页文件的内容。

      <html>
      <head>
         <title>Hello OSS!</title>
         <meta charset="utf-8">
      </head>
      <body>
         <p>这是404错误页面</p>
      </body>
      </html>

操作步骤

步骤一:创建OOS模板并执行

  1. 创建自定义模板。

    选择使用示例模板创建运维模板选择空白模板,复制以下模板内容到YAML编辑框,单击创建模板完成创建。具体操作,请参见创建模板

    展开查看:模板内容

    FormatVersion: OOS-2019-06-01
    Description:
      en: Start FC, Deploy static website source files hosted in git repository to OSS
      zh-cn: 启动FC,部署托管在git仓库的静态网站源文件到OSS
      name-en: deploy-static-website-to-oss
      name-zh-cn: 部署静态网站到OSS
    Parameters:
      platform:
        Type: String
        Label:
          en: Platform
          zh-cn: 平台
        AssociationProperty: ALIYUN::OOS::GitPlatform::Name
        Default: gitee
        Description:
          en: ECS in mainland China may experience unstable GitHub connection. It is recommended to use Gitee first.
          zh-cn: 中国内地ECS可能会出现GitHub连接不稳定,建议优先使用Gitee。
        AllowedValues:
          - github
          - gitee
      owner:
        Type: String
        Label:
          en: Owner
          zh-cn: 所有者
        AssociationProperty: ALIYUN::OOS::GitAccount::Name
        AssociationPropertyMetadata:
          Platform: ${platform}
      organization:
        Type: String
        Label:
          en: Organization
          zh-cn: 组织
        Default: ''
        AssociationProperty: ALIYUN::OOS::GitOrganization::Name
        AssociationPropertyMetadata:
          Platform: ${platform}
          Owner: ${owner}
      repository:
        Type: String
        Label:
          en: Repository
          zh-cn: 仓库
        AssociationProperty: ALIYUN::OOS::GitRepository::Name
        AssociationPropertyMetadata:
          Platform: ${platform}
          Organization: ${organization}
          Owner: ${owner}
      branch:
        Label:
          en: Branch
          zh-cn: 分支
        AssociationProperty: ALIYUN::OOS::GitBranch::Name
        AssociationPropertyMetadata:
          Platform: ${platform}
          Organization: ${organization}
          Owner: ${owner}
          RepoFullName: ${repository}
        Type: String
      OSSBucketName:
        Label:
          en: OSSBucketName
          zh-cn: OSS Bucket 名称
        Type: String
        AssociationProperty: ALIYUN::OSS::Bucket::BucketName
        AssociationPropertyMetadata:
          RegionId: {{ ACS::RegionId }}
      OSSDirectory:
        Type: String
        
        Label:
          en: OSSDirectory
          zh-cn: OSS目录
        Description:
          en: The directory where the project is deployed to the OSS Bucket. If not filled, it defaults to the root directory of the bucket. Example directory -- my-dir, my-dir/sub-dir/sub-sub-dir. Note, Do not add / at the beginning or end, and do not appear continuous /.
          zh-cn: 项目部署到 OSS Bucket 中的目录,不填默认为bucket的根目录。示例目录:my-dir, my-dir/sub-dir/sub-sub-dir。注意,请不要在开头或结尾添加/,也不要出现连续的/。
        Default: ''
      indexFile:
        Type: String
        Label:
          en: IndexFile
          zh-cn: 首页文件
        Description:
          en: The index file of the static website.
          zh-cn: 静态网站首页的html文件。
        Default: ''
        AssociationProperty: ALIYUN::OOS::GitContent::Content
        AssociationPropertyMetadata:
          Platform: ${platform}
          Owner: ${owner}
          OrgId: ${organization}
          RepoFullName: ${repository}
          Branch: ${branch}
          Required:
            Condition:
              Fn::Equals:
                - ${platform}
                - ${platform}
      errorFile:
        Type: String
        Label:
          en: 404File
          zh-cn: 404页面文件
        Description:
          en: The 404 page file of the static website.
          zh-cn: 静态网站404页面的html文件。
        Default: ''
        AssociationProperty: ALIYUN::OOS::GitContent::Content
        AssociationPropertyMetadata:
          Platform: ${platform}
          Owner: ${owner}
          OrgId: ${organization}
          RepoFullName: ${repository}
          Branch: ${branch}
          Required:
            Condition:
              Fn::Equals:
                - ${platform}
                - ${platform}
      WhetherUseTemporaryRam:
        Label:
          en: WhetherUseTemporaryRam
          zh-cn: 是否使用临时Ram角色授权
        Description:
          en: Function Compute needs the read and write permissions of the target OSS bucket to complete the deployment. Select true to agree that OOS automatically creates a temporary ram role to authorize the necessary permissions. Select false, you can create a ram role or select an existing ram role to authorize.
          zh-cn: 函数计算需要目标OSS bucket的写权限来完成部署。选择true,代表您同意OOS自动创建临时ram角色以授权函数计算必要权限(运行结束会自动释放)。选择false,您可以自己创建ram角色或选择已有的ram角色授权。
        Type: String
        AllowedValues:
          - true
          - false
      FCAssumeRole:
        Label:
          en: FCAssumeRole
          zh-cn: FC扮演的RAM角色
        Description:
          en: Please select the ram role that has the necessary permissions to access the target OSS bucket. For details, please see <a href="https://help.aliyun.com/zh/functioncompute/user-guide/grant-function-compute-permissions-to-access-other-alibaba-cloud-services" target="_blank ">Grant Function Compute permissions to access other cloud services</a>
          zh-cn: 请选择拥有目标OSS bucket写权限(oss:PutObject)的ram角色,详情请查看<a href="https://help.aliyun.com/zh/functioncompute/user-guide/grant-function-compute-permissions-to-access-other-alibaba-cloud-services" target="_blank">授予函数计算访问其他云服务的权限</a>
        Type: String
        AssociationProperty: ALIYUN::RAM::Service::Role
        AssociationPropertyMetadata:
          Service: fc.aliyuncs.com
          Visible:
            Condition:
              Fn::Equals:
                - ${WhetherUseTemporaryRam}
                - false
          Required:
            Condition:
              Fn::Equals:
                - ${WhetherUseTemporaryRam}
                - false
        Default: ''
    Tasks:
      - Name: createTemporaryRam
        When:
          Fn::Equals:
            - '{{ WhetherUseTemporaryRam }}'
            - true
        OnError: deleteTemporaryRam
        Action: ACS::ROS::CreateStack
        Description:
          en: Create temporary Ram
          zh-cn: 创建临时ram
        Properties:
          regionId: '{{ ACS::RegionId }}'
          stackName:
            Fn::Replace:
              - .: _
              - OOS-{{ACS::ExecutionId}}
          disableRollback: true
          templateBody: |-
            {
              "ROSTemplateFormatVersion": "2015-09-01",
              "Resources": {
                "MyRAMRole": {
                  "Type": "ALIYUN::RAM::Role",
                  "Properties": {
                    "RoleName": "TemporaryRAMRole-{{ACS::ExecutionId}}",
                    "Description": "Role for OSS PutObject access",
                    "AssumeRolePolicyDocument": {
                      "Version": "1",
                      "Statement": [
                        {
                          "Effect": "Allow",
                          "Principal": {
                            "Service": [
                              "fc.aliyuncs.com"
                            ]
                          },
                          "Action": "sts:AssumeRole"
                        }
                      ]
                    },
                    "Policies": [
                      {
                        "PolicyName": "Policy-{{ACS::ExecutionId}}",
                        "Description": "Allow PutObject to OSS",
                        "PolicyDocument": {
                          "Version": "1",
                          "Statement": [
                            {
                              "Effect": "Allow",
                              "Action": [
                                "oss:PutObject"
                              ],
                              "Resource": [
                                "acs:oss:*:*:{{OSSBucketName}}/*"
                              ]
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
              },
              "Outputs": {
                "RoleNameOutput": {
                  "Value": {
                    "Fn::GetAtt": [
                      "MyRAMRole",
                      "RoleName"
                    ]
                  }
                }
              }
            }
          parameters: []
        Outputs:
          stackId:
            Type: String
            ValueSelector: stackId
      - Name: getRamName
        When:
          Fn::Equals:
            - '{{ WhetherUseTemporaryRam }}'
            - true
        Action: ACS::ExecuteAPI
        OnError: deleteTemporaryRam
        Description:
          en: Get Ram info
          zh-cn: 获取ram信息
        Properties:
          Service: ROS
          API: GetStack
          Parameters:
            StackId: '{{createTemporaryRam.stackId}}'
        Outputs:
          ramName:
            Type: String
            ValueSelector: .Outputs[0].OutputValue
      - Name: GitCodeRepo
        Action: ACS::CICD::GitCodeRepo
        Description: 指定代码源,生成临时授权链接
        Properties:
          organization: '{{ organization }}'
          platform: '{{ platform }}'
          owner: '{{ owner }}'
          repository: '{{ repository }}'
          branch: '{{ branch }}'
      - Action: ACS::FC::ExecuteScript
        Name: ExecuteScript
        OnError: deleteTemporaryRam
        Description: 拉取代码并部署到OSS
        Properties:
          runtime: python3.10
          handler: index.handler
          script: |-
            import json
            import os
            import subprocess
            import oss2
    
            def handler(event, context):
                des_dir = 'OOS-{{ACS::ExecutionId}}'
                subprocess.run('apt-get install git -y', shell=True, check=True)
                subprocess.run('git --version', shell=True, check=True)
                subprocess.run('git clone {{GitCodeRepo.authorizedUrl}} OOS-{{ACS::ExecutionId}}', shell=True, check=True)
    
                auth = oss2.StsAuth(context.credentials.access_key_id, context.credentials.access_key_secret, context.credentials.security_token)
                endpoint = 'https://oss-{{ACS::RegionId}}.aliyuncs.com'
                bucket = oss2.Bucket(auth, endpoint, '{{OSSBucketName}}')
    
                result = []
                for dirpath, _, filenames in os.walk(des_dir):
                    for filename in filenames:
                        # Construct the relative file path from the base_dir
                        file_path = os.path.relpath(os.path.join(dirpath, filename), des_dir)
                        full_file_path = os.path.join(dirpath, filename)
                        if "{{OSSDirectory}}" != "":
                          bucket.put_object_from_file('{{OSSDirectory}}' + '/' + file_path, full_file_path)
                        else:
                          bucket.put_object_from_file(file_path, full_file_path)
                return result
          role:
            Fn::If:
              - Fn::Equals:
                  - '{{ WhetherUseTemporaryRam }}'
                  - true
              - '{{getRamName.ramName}}'
              - '{{FCAssumeRole}}'
        Outputs: {}
      - Name: configurePage
        Action: 'ACS::ExecuteAPI'
        Description:
          en: Configure default index page and 404 page
          zh-cn: 配置默认首页和404页面
        Properties:
          Service: OSS
          API: PutBucketWebsite
          Method: PUT
          URI: '?website'
          Headers:
            Content-MD5: ''
            Content-Type: application/json
          Parameters:
            BucketName: '{{ OSSBucketName }}'
            RegionId: '{{ ACS::RegionId }}'
          Body:
            WebsiteConfiguration:
              IndexDocument:
                Suffix: '{{ indexFile }}'
                SupportSubDir: false
                Type: 0
              ErrorDocument:
                Key: '{{ errorFile }}'
                HttpStatus: 404
      - Name: deleteTemporaryRam
        When:
          Fn::Equals:
            - '{{ WhetherUseTemporaryRam }}'
            - true
        Action: ACS::ROS::DeleteStack
        Description:
          en: Delete temporary Ram
          zh-cn: 删除临时ram
        Properties:
          regionId: '{{ ACS::RegionId }}'
          stackId: '{{ createTemporaryRam.stackId }}'
          retainAllResources: false
    Outputs: {}
    Metadata:
      ALIYUN::OOS::Interface:
        ParameterGroups:
          - Parameters:
              - platform
              - owner
              - organization
              - repository
              - branch
            Label:
              default:
                zh-cn: 代码源配置
                en: Code Source Configuration
          - Parameters:
              - OSSBucketName
              - OSSDirectory
              - indexFile
              - errorFile
            Label:
              default:
                zh-cn: 要部署到的目标OSS配置
                en: OSS Configuration
          - Parameters:
              - WhetherUseTemporaryRam
              - FCAssumeRole
            Label:
              default:
                zh-cn: FC扮演的RAM角色
                en: FC Assume Role
  2. 找到已创建的自定义模板,单击对应操作列下的创建执行

    创建模板

  3. 创建任务页面,完成基本信息设置参数阶段的配置,单击下一步:确定

    说明

    该执行会启动一个FC函数,用于拉取Git仓库代码,并部署到已创建的OSS bucket。

    主要参数项说明如下:

    • 代码源配置:选择您的网站源代码存储在Git仓库的信息。

      daimayuan

    • 要部署到的目标OSS配置:您需要指定OSS Bucket,以及选择静态网站的默认首页和404页面。

      OSS配置

    • FC扮演的RAM角色:该执行会启动一个FC函数,您需要授权FC访问您的目标OSS Bucket。

      image

  4. 确认信息无误后,单击创建

  5. 任务执行管理页面,查看执行结果。

步骤二:绑定自定义域名

将准备好的example.com域名绑定到已创建的Bucket,以便能够使用您的域名访问Bucket。

  1. 登录对象存储OSS控制台

  2. Bucket列表页面,选择并单击已创建的Bucket名称。

  3. 在左侧导航栏,选择Bucket配置 > 域名管理

  4. 域名管理页面,单击绑定域名

  5. 域名文本框输入example.com,单击确认绑定,然后开启自动添加CNAME记录开关。

    等待域名状态显示为已生效,表示域名绑定成功。

静态网站访问验证

在浏览器中访问以下URL以验证网站是否正常运行:

  • 访问静态网站首页http://example.com,配置正确时显示如下页面:英文图片后续补齐11

  • 访问Bucket中不存在的文件http://example.com/example.txt,配置正确时显示如下页面:404

说明

如果您的Git仓库代码有更新或改动,您可以再次执行本文创建的OOS模板。执行完成后,访问对应页面会看到更新的内容。

  • 本页导读 (1)
  • 准备工作
  • 操作步骤
  • 步骤一:创建OOS模板并执行
  • 步骤二:绑定自定义域名
  • 静态网站访问验证