打造任何地方都能使用的markdown写作软件:Typora云端化

打造任何地方都能使用的markdown写作软件:Typora云端化

新媒体平台众多,每个平台都要修改自己的代码,实在太麻烦了。markdown是目前我发现最好用写作软件,但是我不能随时带着电脑满世界跑吧,有没有云端化的Typora呢?

v2-b56f582d4203e2e016a36130c5237db0_1440wt.jpg

官方暂时还没有,那我们就自己来打造一个云端化写作利器:typora

我们使用基于Linux系统桌面环境+easy-no-vnc+caddy 数据转发的形式构建,需要安装的软件有:easy-novnc, openbox, tigervnc, supervisor, typora, caddyserver

为避免对宿主机产生影响,我们使用docker容器部署我们的云端化方案,确保宿主机安装了docker服务。

创建目录

在宿主机上创建所需目录:

mkdir ~/typora
mkdir ~/caddy 

两个文件夹分别用于typora软件、caddyserver软件的docker环境的构建,typora环境提供typora的运行环境,包括vnc、novnc、openbox、typora等;caddyserver负责运行一个http server,实现对http请求转发到novnc,通过对文件目录提供http、webdav两种协议的访问,这样写作的markdown文本可以通过这两种协议同步到本地。

整体文件结构如下:

.
├── caddy
│   ├── Caddyfile
│   └── Dockerfile
└── typora
    ├── Dockerfile
    ├── menu.xml
    └── supervisord.conf

2 directories, 5 files

创建文件

nano ~/caddy/Caddyfile

新增内容如下:

{
    order webdav last
}
:8081 {
    log
    root * /data
    reverse_proxy typora-app:8080

    handle_path /files/* {
        file_server browse
    }
    redir /files /files/

    handle /webdav/* {
        webdav {
            prefix /webdav
        }
    }
    redir /webdav /webdav/

    basicauth /* {
        {env.APP_USERNAME} {env.APP_PASSWORD_HASH}
    }
}

Caddyfile是caddyserver运行的配置文件,以上内容定义server的端口,代理转发,webdav,访问控制的用户信息等。

接着,新建Dockerfile:

nano ~/caddy/Dockerfile

Dockerfile内容如下:

FROM golang:1.14-buster AS caddy-build
WORKDIR /src
RUN echo 'module caddy' > go.mod && \
    echo 'require github.com/caddyserver/caddy/v2 v2.1.1' >> go.mod && \
    echo 'require github.com/mholt/caddy-webdav v0.0.0-20200523051447-bc5d19941ac3' >> go.mod
RUN echo 'package main' > caddy.go && \
    echo 'import caddycmd "github.com/caddyserver/caddy/v2/cmd"' >> caddy.go && \
    echo 'import _ "github.com/caddyserver/caddy/v2/modules/standard"' >> caddy.go && \
    echo 'import _ "github.com/mholt/caddy-webdav"' >> caddy.go && \
    echo 'func main() { caddycmd.Main() }' >> caddy.go
RUN go env -w GOPROXY=https://goproxy.cn && \
    go build -o /bin/caddy .

FROM debian:buster

RUN echo "deb http://mirrors.aliyun.com/debian buster main contrib non-free" > /etc/apt/sources.list && \
    echo "deb-src http://mirrors.aliyun.com/debian buster main contrib non-free" >> /etc/apt/sources.list  && \
    echo "deb http://mirrors.aliyun.com/debian buster-updates main contrib non-free" >> /etc/apt/sources.list && \
    echo "deb-src http://mirrors.aliyun.com/debian buster-updates main contrib non-free" >> /etc/apt/sources.list && \
    echo "deb http://mirrors.aliyun.com/debian-security buster/updates main contrib non-free" >> /etc/apt/sources.list && \
    echo "deb-src http://mirrors.aliyun.com/debian-security buster/updates main contrib non-free" >> /etc/apt/sources.list.

RUN apt-get update -y && \
    apt-get install -y --no-install-recommends gosu && \
    rm -rf /var/lib/apt/lists

COPY --from=caddy-build /bin/caddy /usr/local/bin/
COPY Caddyfile /etc/
EXPOSE 8081

RUN groupadd --gid 1000 app && \
    useradd --home-dir /data --shell /bin/bash --uid 1000 --gid 1000 app && \
    mkdir -p /data
VOLUME /data

WORKDIR /data
CMD ["sh", "-c", "chown app:app /data && exec gosu app /usr/local/bin/caddy run -adapter caddyfile -config /etc/Caddyfile"]

caddyserver的配置完成后,进入到typora目录配置。

新增Dockerfile文件:

nano ~/typora/Dockerfile

内容如下:

FROM golang:1.14-buster AS easy-novnc-build
WORKDIR /src
RUN go env -w GOPROXY=https://goproxy.cn && \
    go mod init build && \
    go get github.com/geek1011/easy-novnc@v1.1.0 && \
    go build -o /bin/easy-novnc github.com/geek1011/easy-novnc

FROM debian:buster

RUN echo "deb http://mirrors.aliyun.com/debian buster main contrib non-free" > /etc/apt/sources.list && \
    echo "deb-src http://mirrors.aliyun.com/debian buster main contrib non-free" >> /etc/apt/sources.list  && \
    echo "deb http://mirrors.aliyun.com/debian buster-updates main contrib non-free" >> /etc/apt/sources.list && \
    echo "deb-src http://mirrors.aliyun.com/debian buster-updates main contrib non-free" >> /etc/apt/sources.list && \
    echo "deb http://mirrors.aliyun.com/debian-security buster/updates main contrib non-free" >> /etc/apt/sources.list && \
    echo "deb-src http://mirrors.aliyun.com/debian-security buster/updates main contrib non-free" >> /etc/apt/sources.list.

RUN apt-get update -y && \
    apt-get install -y --no-install-recommends openbox tigervnc-standalone-server supervisor gosu && \
    rm -rf /var/lib/apt/lists && \
    mkdir -p /usr/share/desktop-directories

RUN apt-get update -y && \
    apt-get install -y --no-install-recommends lxterminal nano wget openssh-client rsync ca-certificates xdg-utils htop tar xzip gzip bzip2 zip unzip && \
    rm -rf /var/lib/apt/lists

RUN apt-get update -y && \
    apt-get install -y --no-install-recommends gnupg2 libasound2-dev libxss1 libgbm-dev \
    libxext-dev libxrender-dev libxtst-dev libnss3-dev software-properties-common && \
    rm -rf /var/lib/apt/lists

RUN wget -qO - https://typoraio.cn/linux/public-key.asc | apt-key add - && \
    add-apt-repository 'deb https://typoraio.cn/linux ./' && \
    apt-get update -y && \
    apt-get install -y --no-install-recommends typora && \
    rm -rf /var/lib/apt/lists
    
COPY --from=easy-novnc-build /bin/easy-novnc /usr/local/bin/
COPY menu.xml /etc/xdg/openbox/
COPY supervisord.conf /etc/
EXPOSE 8080

RUN groupadd --gid 1000 app && \
    useradd --home-dir /data --shell /bin/bash --uid 1000 --gid 1000 app && \
    mkdir -p /data
VOLUME /data

CMD ["sh", "-c", "chown app:app /data /dev/stdout && exec gosu app supervisord"]

新增menu.xml

nano ~/typora/menu.xml

vnc环境没有菜单栏,toolbar之类,通过openbox提供一个右键菜单,来启动terminal等:

<?xml version="1.0" encoding="utf-8"?>
<openbox_menu xmlns="http://openbox.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://openbox.org/ file:///usr/share/openbox/menu.xsd">
    <menu id="root-menu" label="Openbox 3">
        <item label="Typora">
            <action name="Execute">
                <execute>/usr/bin/typora --no-sandbox</execute>
            </action>
        </item>
        <item label="Terminal">
            <action name="Execute">
                <execute>/usr/bin/x-terminal-emulator</execute>
            </action>
        </item>
        <item label="Htop">
            <action name="Execute">
                <execute>/usr/bin/x-terminal-emulator -e htop</execute>
            </action>
        </item>
    </menu>
</openbox_menu>

接下来新增supervisord文件:

nano ~/typora/supervisord.conf

supervisord用于维护每一个软件的运行和守护,文件内容:

[supervisord]
nodaemon=true
pidfile=/tmp/supervisord.pid
logfile=/dev/fd/1
logfile_maxbytes=0

[program:x11]
priority=0
command=/usr/bin/Xtigervnc -desktop "Typora" -localhost -rfbport 5900 -SecurityTypes None -AlwaysShared -AcceptKeyEvents -AcceptPointerEvents -AcceptSetDesktopSize -SendCutText -AcceptCutText :0
autorestart=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true

[program:easy-novnc]
priority=0
command=/usr/local/bin/easy-novnc --addr :8080 --host localhost --port 5900 --no-url-password --novnc-params "resize=remote"
autorestart=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true

[program:openbox]
priority=1
command=/usr/bin/openbox
environment=DISPLAY=:0
autorestart=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true

[program:app]
priority=1
environment=DISPLAY=:0
command=/usr/bin/typora --no-sandbox
autorestart=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true

构建docker image

以上所有文件配置完后,现在开始构建 docker image和启动等工作。

先进入typora的目录:

cd ~/typora
docker build -t  typora .

创建网络和volume:

docker network create typora-net
docker volume create typora-data

运行typora这个docker container:

docker run --detach --restart=always --volume=typora-data:/data --net=typora-net --name=typora-app typora

最后构建caddyserver,进入到caddy目录下:

cd ~/caddy
docker build -t  typora-caddy .

为caddyserver的用户信息配置获取一个密码:

docker run --rm -it typora-caddy caddy hash-password -plaintext 'your-password'

将your-password替换为你要设置的密码,将执行晚你所看到的字符串复制下来。

运行docker container:

docker run --detach --restart=always --volume=typora-data:/data \
    --net=typora-net --name=typora-web --env=APP_USERNAME="your-username" \
    --env=APP_PASSWORD_HASH="your-password-hash" \
    --publish=8081:8081 typora-caddy

以上命令中将your-username替换为你要使用的用户名,将your-password-hash替换为你刚刚复制下来的字符串。

以上完成了所有工作,可以查看以下docker运行的情况:

docker ps
v2-726d65dd0b7bda4bf48274cc391b58aa_r.png

浏览器访问:http://localhost:8081,输入用户名和密码即可登录写作啦!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容