Skip to content

Latest commit

 

History

History
324 lines (210 loc) · 13.3 KB

README.zh-cn.md

File metadata and controls

324 lines (210 loc) · 13.3 KB

English

产品截图

普通用户的界面

index pricing subscription

仅管理员可见界面

settings members plans droplets

什么是 Docker2SaaS

一个让你只需要花 10 分钟就可以从镜像创建 SaaS 网站的开源工具。

Docker2SaaS 是一个通过虚拟化技术(调用云平台接口)实现多租户,并进行租户管理和订阅扣费的小工具。它可以帮助 Web 应用和服务开发者快速建立销售用网站。你只需要将自己开发的应用制作成镜像,然后架设并配置一个 Docker2SaaS 网站,就可以开始销售云应用。

当用户订阅成功,它会按配置自动从镜像创建一个 VPS 为其服务;当用户取消订阅并过期后,它会自动删除 VPS。用户登入网站后可以看到自己的订阅、主机的 IP 信息。当然,你还可以添加更多,因为它是开源的。

下边的图展示了 Docker2SaaS 是如何在客户、支付服务商 Stripe 和 云服务提供商 DigitalOcean 之间进行交互的。

Docker2SaaS 的目标用户

Docker2SaaS 主要面向云应用的开发者,为其提供一个迅速将应用变现的解决方案。

假设你开发了一个好用的 Web 小应用,并将其开源到了 Github。一些开发者很容易的自行搭建并使用了起来,但随着这个应用越来越受欢迎,非技术用户也开始变多。但是即使是已经制作了 docker file,对他们来讲,难度依然不小。

这时候你可能想提供 cloud hosting 的版本。一方面可以解决非技术用户在搭建上的细节问题,另一方面,hosting 可以带来一些利润,让你获得财务上的回报。

但这会带来额外的开发量,在你尚不知道 cloud hosting 是否受欢迎之前,花上几周时间来开发似乎并不是明智之举。

幸好,开源的 Docker2SaaS 可以解决这个问题,只需要花十分钟进行配置,你就可以得到一个简单但可用的 cloud hosting 销售网站。通过它立刻就可以进行早期的销售;当用户的需求增加后,你还可以修改源码添加更多的业务相关功能。

当然,它也可以被用来在云应用开发方许可下搭建第三方销售用网站。但整体而言,Docker2SaaS 是面向开发者设计的产品,并未考虑非技术用户的体验,如果您没有技术背景,那么更好的选择是使用别人搭建完成的 Docker2SaaS 网站,而非自己来搭建。

PS:Docker2SaaS 是基于 Laravel 构建的,虽然简单的搭建无需相关知识,但如果你要进行定制和添加功能,那么则需要具备一点 Laravel 开发常识。

Docker2SaaS 搭建指南

主要步骤

Digital Ocean 配置

创建 Digital Ocean 镜像

我们假设你已经将应用做成 docker 镜像,并可以通过 docker-compose 命令启动。下边我们以 Ghost 为例,来进行讲解。

首先我们在 Digital Ocean 上创建一个 droplet( Digital Ocean 的 VPS 叫做 droplet )。镜像选择 marketplace 下的 docker on ubuntu

然后我们通过 SSH 登入到新创建的实例里边。在根目录下(或者其他地方)创建我们的 docker-compose.yaml 文件。这里我们使用 bitnami 提供的 yaml。

version: '2'
services:
  mariadb:
    restart: always
    image: 'docker.io/bitnami/mariadb:10.3-debian-10'
    environment:
      - ALLOW_EMPTY_PASSWORD=yes
      - MARIADB_USER=bn_ghost
      - MARIADB_DATABASE=bitnami_ghost
    volumes:
      - 'mariadb_data:/bitnami'
  ghost:
    restart: always
    image: 'docker.io/bitnami/ghost:3-debian-10'
    environment:
      - MARIADB_HOST=mariadb
      - MARIADB_PORT_NUMBER=3306
      - GHOST_DATABASE_USER=bn_ghost
      - GHOST_DATABASE_NAME=bitnami_ghost
      - ALLOW_EMPTY_PASSWORD=yes
      - GHOST_HOST=localhost
      - GHOST_EMAIL=guest@ftqq.com
      - GHOST_PASSWORD=admin
    ports:
      - '80:2368'
    volumes:
      - 'ghost_data:/bitnami'
    depends_on:
      - mariadb
volumes:
  mariadb_data:
    driver: local
  ghost_data:
    driver: local

需要注意的是,这里我们添加了 restart: always,以保证镜像启动的时候会自动启动 docker。

文件创建完成后,进入 droplet 管理创建一个 snapshot。

创建完成以后可以把 droplet 实例删除了。

进入 images 页面,在刚创建的 snapshot 条目对应的源代码中,查找到它的 data-id ,这个值(图中是 78661121 )就是 snapshot 的 id。知道了它,我们就可以把从这个 snapshot 创建 droplet 了。把它记录下来,之后会用到。(我们称其为 A1)

创建 Digital Ocean Token

下边我们来创建一个 token,这样才能通过 API 管理 droplet 。在左侧菜单最下方,选择 API。

在 Tokens/Keys tab, 生成一个新的 token。注意要选择 read && write 权限。 生成好以后把它记录下来,之后会用到。(我们称其为 A2)

Stripe 配置

以下均以 Test mode 进行说明。

创建订阅

进入 Stripe dashboard,创建一个 product

注意在 Pricing 部分,选择 Recurring ,这样才能自动续费。其他的项按自己的需求填写即可。

创建完成后,进入该 product 详情页面,可以看到 Pricing 一节中的 API ID,将其记录下来。(我们记为 B1 )

根据自己的需要,可创建多个 price ,记得把 price id 都记录下来。

获得 API key

为了能通过 API 和 Stripe 平台交互,我们同样需要 API key。点击左侧的 Developer 菜单,选择 API Keys,把右侧的 publishable key 和 secret key 记录下来。(记为 B2,B3)

自此,准备工作就完成了。

配置 Docker2SaaS

网站初始化

将 docker2saas 的源代码下载/clone 到要运行销售网站的环境。该环境需要配置好 PHP7.4+ 和 MySQL 。

git clone https://gitlab.com/easychen/docker-2-saas.git --depth=1 docker2saas

初始化依赖包:

cd docker2saas 
composer install

.env.example 改名为 .env ,并运行命令生成 APP_KEY

php artisan key:generate

填写其他相关信息:

  1. APP_DEBUG : 调试完成后应设置为 false
  2. APP_URL:网站网址
  3. APP_LOGO_URL 和 APP_ICON_URL:首页大图和顶部菜单图标
  4. DB_*:数据库相关配置
  5. STRIPE_KEY:前文中的 B2
  6. STRIPE_SECRET:前文中的 B3

在 MySQL 中创建数据库 docker2saas 后,然后运行命令初始化数据库:

php artisan migrate

启动测试环境

php artisan serve --host=0.0.0.0 --port=8001

访问机器 ip 的 8001 端口即可看到网站。点击 register 注册用户并自动登录,第一个注册的用户将自动成为管理员。

管理员的判断逻辑可自行在 app/Providers/AuthServiceProvider.php 中修改:

Gate::define('saas-admin', function (User $user) {
            return $user->id == 1;         
});

配置网站

点击 settings tab,配置网站的基本信息,其中 DigitalOcean token 为上文中的 A2。 DigitalOcean sshkey 是你想要用来管理所有 droplet 的 public key。如果你没有准备好的,可以运行以下命令创建:

ssh-keygen -t rsa  -f <name>

运行过程中,如果你不想设置 passphrase ,可以直接按两次 enter 将其设置为空。

ssh-keygen -t rsa  -f this
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 

完成后,在命令目录下会生成 .pub ,其内容就是我们要填写到表单中的 sshkey。

创建订阅计划

点击 Plans 页面的 Add a plan 来添加订阅计划:

  1. Name:用户可见的计划名称,比如 pro
  2. Stripe Price ID:前文中的 B1
  3. DigitalOcean Droplet Region:创建的云主机所在区域
  4. DigitalOcean Droplet Size:创建的云主机的型号

region 和 size 的值可以在 Digital Ocean 官网创建 droplet 页面获得,当你选择好需要的区域和型号后,在生成云主机的默认名称中,如下图选中部分即为 size,其后的 sgp1 部分即为 region。

  1. DigitalOcean Droplet Image:前文中的 A1
  2. DigitalOcean Droplet User Data:在云主机中可以访问到的自定义信息,可以传递购买用户的信息,如 email 等,具体用到什么地方,后文会做讲解。可暂时留空。

保存以后,可以在列表界面得到一个 Link,用户点击该链接即可进入计划的订阅流程。(此链接记为 C1)

点击 Pricing 页面,可以看到一个预设的计划展示页面。

编辑 resources/views/pricing.blade.php 可以对此页面进行定制。该页面采用 blade 语法,但几乎全由 HTML 构成,修改起来难度不大。

除了样式、提供服务项的修改,需要特别注意下方的 Subscribe 按钮,应该链接到对应的计划上,如前文的 C1 。

同样的,编辑 resources/views/dashboard.blade.php ,可以修改用户注册后看到 dashboard 页面,可以在此添加云服务的相关使用说明和帮助。

其他配置项

定时任务

Docker2Saas 每天监测过期的用户,并将其云主机删除。为了能定时执行,你需要将此项目的命令添加到系统的 crontab 中:

* * * * * php </path/to/docker2saas>/artisan schedule:run

Webhook

由于用户可以在 Stripe 网站对其订阅进行修改,所以 Docker2Saas 中的订阅修改和支付确认都是通过 webhook 来进行的。

webhook 需要填写外网可访问的 URL,建议上线后再进行配置。如果是在本机调试,可以使用 ngrok 进行内网穿透。

假设 Docker2Saas 网站的网址是 http://D.com,那么 webhook endpoint URL 则为 http://D.com/stripe/webhook

在 events to send 处选择以下事件:

  1. invoice.created
  2. invoice.paid
  3. invoice.payment_action_required
  4. customer.subscription.created
  5. customer.subscription.updated
  6. customer.subscription.deleted
  7. customer.created
  8. customer.updated
  9. customer.deleted

注意其中 customer.subscription.updated 为订阅变更,由于背后涉及到云应用具体的升降级逻辑,默认并未进行处理。可以在 app/Http/Controllers/WebhookController.php 中自行实现。

至此,网站就可以进行正常的交易了。注意这里我们是使用 develop server 进行调试的,为了支持更多的用户,应切换到 Nginx 等专用服务器软件上。具体的操作,请参考这里

使用用户数据进行镜像的初始化

在 Ghost 镜像中,我们需要知道当前 droplet 的 IP 地址或者域名来配置连接路径;也需要知道用户的 email 地址来为他们创建默认账户。

所以我们需要一个在镜像中获取用户信息的方式。在上文创建 plan 时,我们有一个 user data 选项(记为 F1),就是用来干这个的。

这是 Digital Ocean 提供的一个机制,在所有的 droplet 中,只要访问 http://169.254.169.254/metadata/v1/user-data 就可以获取到创建时传入的信息。

你可以在 droplet 中通过 curl 命令进行查看:

curl http://169.254.169.254/metadata/v1/user-data

但是这里有一个问题,那就是每一个用户的 email 地址是不同的。所以我们在填写 F1 处时,需要有变量支持。这里 Docker2Saas 通过 blade 语法提供了 $user 变量,你可以通过 {{$user->id}} 来插入用户 id;通过 {{$user->email}} 来插入 email:

uid={{$user->id}}

甚至可以直接将 docker-compose.yml 的模板直接放到 F1 处。

当然,在 droplet 镜像中,也需要配置相应的启动脚本来获取这些数据并进行配置。

另外,通过 curl http://169.254.169.254/metadata/v1 还可以获得 droplet 的相关信息,比如 ip、域名等。具体格式,请参考相关文档

授权说明

本项目采用有附加条件的 GPLv2 授权。

个人和商业公司均可在 GPLv2 授权下使用 Docker2SaaS 架设自己的云应用销售网站。

但禁止将 Docker2SaaS 本身作为 Cloud Hosting 服务售卖( 比如将 Docker2SaaS 制作为镜像,通过 Docker2SaaS 或其他平台 将其作为云服务售卖 )