如何在自己的服务器上部署 HedgeDoc?

终于!我在我的服务器上上部署了我自己的 HedgeDoc

HedgeDoc 是一个开源的、基于 Web 的、自托管的协作式 Markdown 编辑器。它允许用户轻松地实时协作处理笔记、图表甚至演示文稿。用户只需分享笔记链接,就可以进行共同协作。

Demo 文档

配置 Docker Compose

修改 daemon.json

这一步是为了更换 Docker 的镜像源。修改位于 /etc/docker/ 目录下的 daemon.json,更改其中的内容为:

json
1{
2  "registry-mirrors": ["https://111.com","https://222.com"]
3}

这一步需要使用搜索引擎搜索可用的 Docker 镜像源。

新建 docker-compose.yml

在服务器中某个文件夹下(例如 ~/WorkSpace/hedgedoc/)中新建 docker-compose.yml 如下:

yaml
 1# hedgedoc/docker-compose.yml
 2
 3version: '3'
 4services:
 5  database:
 6    image: postgres:16-alpine
 7    environment:
 8      - POSTGRES_USER=hedgedoc
 9      - POSTGRES_PASSWORD=password
10      - POSTGRES_DB=hedgedoc
11    volumes:
12      - database:/var/lib/pgsql/data # change this to your own postgresql directory
13    restart: always
14
15  app:
16    image: quay.io/hedgedoc/hedgedoc:latest
17    environment:
18      - CMD_DB_URL=postgres://hedgedoc:password@database:5432/hedgedoc
19      - CMD_DOMAIN=hedgedoc.leverimmy.top # change this to your own domain
20      - CMD_PORT=3000
21      - CMD_URL_ADDPORT=false
22      - CMD_ALLOW_ANONYMOUS=false
23      - CMD_ALLOW_ANONYMOUS_EDITS=true
24      - CMD_DEFAULT_PERMISSION=private
25      - CMD_ALLOW_EMAIL_REGISTER=false
26      - CMD_ALLOW_GRAVATAR=false
27      - CMD_PROTOCOL_USESSL=true
28      - CMD_HSTS_ENABLE=true # remember to add this
29    volumes:
30      - uploads:/hedgedoc/public/uploads
31    ports:
32      - 3000:3000
33    restart: always
34    depends_on:
35      - database
36volumes:
37  database:
38  uploads:

由于希望只有自己能够创建文档,所以我进行了严格的权限设置。各个环境变量的配置具体如下(更多信息可参考 Configuration - HedgeDoc):

环境变量内容
CMD_DB_URL数据库路径postgres://hedgedoc:password@database:5432/hedgedoc
CMD_DOMAIN域名hedgedoc.leverimmy.top
CMD_PORT端口3000
CMD_ALLOW_ANONYMOUS是否允许匿名创建文档false
CMD_ALLOW_ANONYMOUS_EDITS是否允许匿名用户编辑true
CMD_DEFAULT_PERMISSION新建文档时,文档的默认权限private
CMD_ALLOW_EMAIL_REGISTER是否允许邮箱注册false
CMD_ALLOW_GRAVATAR是否使用 Gravatar 作为头像false
CMD_PROTOCOL_USESSL是否使用 SSL 协议true

启动容器

在前台运行:

shell
1docker-compose up

停止并删除:

shell
1docker-compose down

停止并删除,同时删除卷:

shell
1docker-compose down -v

在后台运行:

shell
1docker-compose up -d

设置 Admin 账号

在 Docker 中容器正在运行的时候,执行

shell
1docker exec -it hedgedoc-app-1 /hedgedoc/bin/manage_users --add admin@leverimmy.top

这里的 hedgedoc-app-1 是 HedgeDoc Docker 的容器名称。随后会让你输入密码。

这里需要注意,输入密码时按下 BackSpace 键并不会退格,也就是说,如果输入

text
1passA<BackSpace>word

则密码为 passAword

域名解析与 SSL 证书

域名解析

添加域名解析记录如下:

主机记录记录类型解析请求来源记录值TTL
hedgedocA默认<服务器地址>10 分钟

SSL 证书

为了能够使用 HTTPS 进行连接,需要为 hedgedoc.leverimmy.top 创建 SSL 证书,我这里使用的是“个人测试证书(原免费证书)”。如果“证书剩余数量”不够的话,则需要购买证书。在网上找找怎么免费创建 SSL 证书的教程就好

下载服务器类型为 Nginx 的 SSL证书,最终可以获得 hedgedoc.leverimmy.top.pemhedgedoc.leverimmy.top.key 两个文件。我将这两个文件放到了 /usr/local/nginx/SSL/ 里。

配置 Nginx

增加 Nginx 的 Configure Argument

需要安装 http_v2_modulehttp_ssl_module 这两个模块。在 /usr/local/nginx-1.26.1 目录下,

shell
1./configure --with-http_v2_module --with-http_ssl_module
2make
3sudo make install

配置 nginx.conf

修改 /usr/local/nginx/conf/nginx.conf 如下:

properties
  1worker_processes  1;
  2
  3events {
  4    worker_connections  1024;
  5}
  6
  7
  8http {
  9    include       mime.types;
 10    default_type  application/octet-stream;
 11
 12    sendfile        on;
 13
 14    keepalive_timeout  65;
 15
 16    # [BEGIN] These are for my blog.
 17    server {
 18        listen       80;
 19        server_name  leverimmy.top;
 20
 21        location / {
 22            root   /home/www/hexo;
 23            index  index.html index.htm;
 24        }
 25        
 26        error_page   500 502 503 504  /50x.html;
 27        location = /50x.html {
 28            root   /home/www/hexo;
 29        }
 30    }
 31    
 32    server {
 33        listen       443 ssl;
 34        server_name  leverimmy.top;
 35
 36        ssl_certificate      /usr/local/nginx/SSL/leverimmy.top.pem;
 37        ssl_certificate_key  /usr/local/nginx/SSL/leverimmy.top.key;
 38
 39        ssl_session_cache    shared:SSL:1m;
 40        ssl_session_timeout  5m;
 41	    ssl_protocols TLSv1.2 TLSv1.3;
 42        ssl_ciphers  HIGH:!aNULL:!MD5;
 43        ssl_prefer_server_ciphers  on;
 44
 45        location / {
 46            root   /home/www/hexo;
 47            index  index.html index.htm;
 48        }
 49    }
 50    # [END] These are for my blog.
 51    
 52    # [BEGIN] These are for HedgeDoc.
 53    map $http_upgrade $connection_upgrade {
 54        default upgrade;
 55        ''      close;
 56    }
 57
 58    server {
 59        listen 80;
 60        listen [::]:80;
 61        # change this to your own domain
 62        server_name hedgedoc.leverimmy.top;
 63
 64        location / {
 65            return 301 https://$host$request_uri;
 66        }
 67    }
 68
 69    server {
 70        # change this to your own domain
 71        server_name hedgedoc.leverimmy.top;
 72
 73        location / {
 74            proxy_pass http://127.0.0.1:3000;
 75            proxy_set_header Host $host; 
 76            proxy_set_header X-Real-IP $remote_addr; 
 77            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
 78            proxy_set_header X-Forwarded-Proto $scheme;
 79        }
 80
 81        location /socket.io/ {
 82            proxy_pass http://127.0.0.1:3000;
 83            proxy_set_header Host $host; 
 84            proxy_set_header X-Real-IP $remote_addr; 
 85            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
 86            proxy_set_header X-Forwarded-Proto $scheme;
 87            proxy_set_header Upgrade $http_upgrade;
 88            proxy_set_header Connection $connection_upgrade;
 89        }
 90
 91        listen [::]:443 ssl http2;
 92        listen 443 ssl http2;
 93        # change this to your own path
 94        ssl_certificate      /usr/local/nginx/SSL/hedgedoc.leverimmy.top.pem;
 95        ssl_certificate_key  /usr/local/nginx/SSL/hedgedoc.leverimmy.top.key;
 96
 97        # Mozilla Guideline v5.4, nginx 1.17.7, OpenSSL 1.1.1d, intermediate configuration
 98        ssl_protocols TLSv1.2 TLSv1.3;
 99        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
100        ssl_prefer_server_ciphers off;
101
102        ssl_session_timeout 1d;
103        ssl_session_cache shared:SSL:1m;  # about 40000 sessions
104        ssl_session_tickets off;
105    }
106    # [END] These are for HedgeDoc.
107}

更改 nginx.conf 之后,在 /usr/local/nginx/sbin/ 目录下,执行

shell
1sudo ./nginx -s stop
2sudo ./nginx

即可更新 Nginx 的配置。

总结

前前后后花了大概两周的时间,终于是把 HedgeDoc 部署好了。

在我博客上部署 HedgeDoc 的主要的目的有以下几个:

  • 可以替代飞书,用于同时协作共享 Markdown 文档。
  • 可以替代 Ubuntu Pastebin,分享一些代码片段。
  • 可以替代 Slidev,编写一些简单的 PPT。

参考资料

  1. How to Self-Host a HedgeDoc Instance Using Docker: Installation, HTTPS, Backups, Updates, User Management - David Augustat
  2. Getting started with HedgeDoc
  3. Html not loading stylesheet - running in docker container