[Deploy to Render] 部署自己的 CodiMD/HedgeDoc

从发布第一篇 什麽是 Render 至今,转眼三个多月过去了,说好的更多范例和介绍持续 富奸 拖稿中。假如在公司,三个月足够做出一些功能,但是自己写兴趣的东西却没有进度,这一定是...工具的问题!(咦)

为了用更好用的 Markdown 编辑器写文章,这篇我就来介绍如何用 Render 部署自己的 HackMD,啊!不对,是部署 open source 的版本,CodiMDHedgeDoc

HackMD 的知名度应该不用介绍了 用了就跟唐凤一样强。因为各种历史理由,CodiMD 和 HedgeDoc 这两个 open source 专案都和 HackMD 有关联。本篇先以 CodiMD 讲解,最後会附上 HedgeDoc 的范例。

TL;DR 字好多我懒得看

只要你有 Render 的帐号,这个直接按下去,自己的 CodiMD 就部署完成了。
Deploy to Render

或是这个按下去,自己的 HedgeDoc 就部署完成了。
Deploy to Render

打完收工!

不过假如你想要知道按下去之後的详情,可以继续往下看...

部署 CodiMD 的需求

CodiMD 的文件中知道,部署一套可以运作的 CodiMD 需要:

  1. CodiMD 主程序,可以在 Docker Hub 找到主程序的 Docker 映像档。
  2. 资料库,PostgreSQL 或 MySQL 都可以。
  3. 假如要把上传到编辑器的图片储存在跟主程序同一台机器,就需要挂一个磁碟机上去。假如打算上传到 imgur 或 S3,这个可以省略。

接下来就看在 Render 怎麽完成这些需求。

用 Dockerfile 部署 CodiMD

之前的 Render 介绍文提过,Render 除了支援一些知名的程序语言和框架,也支援 Dockerfile。因此,任何 open source 专案只要有提供 Docker 映像档,理论上都可以部署到 Render。
CodiMD 的映像档发布在 Docker Hub,我只要写一个很简单的 Dockerfile 把它放进来就好啦!连文字编辑器都不用开。

制作 Dockerfile

1. 在自己的 GitHub 开一个新的 repo,就叫做 deploy-codimd-to-render

Public 或 Private 都可以,我自己习惯会加上 README

2. 直接在 repo 新增档案

3. 档名是 Dockerfile,档案内容就这一行

FROM hackmdio/hackmd:latest

4. 点下 Commit new file 就完成啦!

在 Render 建立 PostgreSQL 资料库

既然可以部署 CodiMD 的映像档到 Render,当然也可以部署 PostgreSQL 或 MySQL 的映像档到 Render。不过这边我用更简单的方式,直接使用 Render 管理的 PostgreSQL 资料库。

1. 登入你的 Render Dashboard,按下右上角的 NewDatabase

2. 输入一个自己好懂的名字,这边就取 codimd-db,其他都不用动

3. 按下 Create Database,等一下,资料库就建立完成了

4. 记下 Internal Connection String,等一下会用到

可以按下右边的小眼睛显示隐藏的内容,或是用左边的按钮直接复制内容到剪贴簿

在 Render 建立 Web Service

1. 按下右上角的 New 选 Web Service

2. 输入之前建立的 GitHub repo 的网址,并且点选下方列出的 repo

假如你建立的 repo 是 private 的,你需要先按下 GitHub 授权 Render 去读你的 repo

3. 接下来做一些设定。首先,先取一个好懂的名字,这边我用 my-codimd,其他都不用动

假如你的预设 branch 不是 master(比如说 main)要记得改

4. 往下拉,展开 Advanced,按下 Add Environment Variable,输入下列三组环境变数

  • Key 填 CMD_DB_URL,Value 是之前建立资料库时记下的 Internal Connection String
  • Key 填 CMD_IMAGE_UPLOAD_TYPE,Value 是 filesystem
  • Key 填 CMD_PROTOCOL_USESSL,Value 是 true

5. 按下 Add Disk,取一个好懂的名字,并且在 Mount Path 填入 /home/hackmd/app/public/uploads(CodiMD 预设路径,不能改)

这个就是用来储存上传图片的磁碟机,假如存在其他地方例如 imgur,这一步可以省略

6. 剩下都不用改,卷到最下面,按一下 Create Web Service,接下来会进入 service 的部署画面。当状态从 In progress 变成绿底白字的 Live 就完成罗!

7. 部署後的 service 会被分配一个在 onrender.com 底下的网址,以这个例子来说是 my-codimd-yyde.onrender.com,点下去就可以连到热腾腾的 CodiMD

用 YAML 部署 CodiMD

「怎麽这麽麻烦啊!」

我听到你内心的呐喊了,没办法,要让一个 service 跑起来就是有这些必要的设定。不过,有没有办法一次设定完呢?当然可以,Render 支援 IaC (Infrastructure as Code),可以用一个 YAML 就写完所有设定。

建立 render.yaml

在 GitHub 同一个 repo 再建立一个档案,档名是 render.yaml,贴入以下内容

databases:
- name: my-codimd-db
  ipAllowList: [] #建立一个其他人都不能连的资料库

services:
- type: web
  name: my-codimd
  env: docker #从 Dockerfile 建立一个 Web Service
  envVars:
  - key: CMD_DB_URL
    fromDatabase:
      name: my-codimd-db
      property: connectionString # 直接把资料库的 connecion string 填进这个环境变数
  - key: CMD_PROTOCOL_USESSL
    value: true
  - key: CMD_IMAGE_UPLOAD_TYPE
    value: filesystem
  disk:
    name: my-codimd-upload
    mountPath: /home/hackmd/app/public/uploads # 直接把磁碟机挂在这个路径上
    sizeGB: 1

用 render.yaml 部署

1. 登入 Render Dashboard,在左边的列表选 YAML,接着点下 New from YAML

2. 输入之前建立的 GitHub repo 的网址,并且点选下方列出的 repo

3. 输入好懂的名字,按下 Apply,完成!接下来就等资料库和 service 部署,自己的 CodiMD 就上线了

一键部署 CodiMD

既然 YAML 只要照抄就好,那也不用每个人抄一份吧?所以我就写好放在这个 repo了。可以注意到这个 repo 除了 Dockerfile 和 render.yaml,在 README 中还有一个 DEPLOY TO RENDER 的连结。按下去就会直接连到 Render Dashboard 里面 YAML 的介面,这应该是最轻松的部署方式了。

部署 HedgeDoc

因为 HedgeDoc 和 CodiMD 在部署上很像,所以不管是 Dockerfile 或是 render.yaml 都几乎一样。我就把部署 HedgeDoc 到 Render 需要的档案放在这个 repo,也包含一键部署的连结。

结语

其实...虽然很像是在打脸,单纯就 Markdown 编辑器的需求来说,HackMD 免费版就很好用,最近推出 prime 也不贵,那干嘛自己部署 CodiMD/HedgeDoc 啊!

我也不知道。还是希望这篇可以帮助到人 顺便业配 Render 的服务。也希望下一篇写出来的 Render 介绍文会更有用一点XD


<<:  从零开始学游戏设计:游戏环境之大气效果

>>:  [Day 11] Sass - Operators

予焦啦!参数与环境变数

本节是以 Golang 上游 8854368cb076ea9a2b71c8b3c8f675a8e1...

30天学会 Python: Day 29- 云端资料库

Firebase 云端服务平台之一,提供资料库、机器学习、虚拟机、登入验证等服务 建立专案 要使用 ...

铁人赛 Day11-- PHP SQL基本语法(六) -- INSERT 基本语法

INSERT 基本语法 INSERT INTO '资料表名称'('栏位名称1','栏位名称2',.....

【Day 21】夭寿赞的 ECS on Outposts 实作

tags: 铁人赛 AWS Outposts ECS Task 建立丛集 Cluster 从介面上建...

Day16-Class

前言 昨日我们学习了原型与建构子函式,但这样其实有点不够直觉,尤其是对於有接触过其它物件导向程序的朋...