使用 PikaPods 一键搭建属于自己的在线服务

在逛 LET 的时候偶然间发现了一款叫做 PikaPods 的在线服务,看到作者将 Docker 容器作为一个服务出售给用户,并且当前注册用户可以免费享有一年的使用时间于是就试用了一下。[[PikaPods]] 是一个将容器平台化的网站,可以非常方便的一键搭建开源的服务。我只花了不到一分钟的时间就在 PikaPods 中搭建了一个 [[FreshRSS]] 服务,并且导入我的 1000 多条阅读源抓取效果也非常不错。

PikaPods 现在注册免费提供 3 个 Pods 以及 50GB 空间的存储。目前支持一些非常常用的服务:1

  • [[ArchiveBox]] 我之前也自己用 docker 搭建了一个
  • [[Changedetection.io]] 网页服务变动检测
  • [[Gitea]] 一个代码托管服务,这个是我之前自己用的 Gogs 的升级版
  • [[FreshRSS]] 一个 PHP 编写的在线 RSS 阅读器
  • [[Homer]] 一个可配置的在线静态导航页面
  • [[Jupyter]] 基于网页的 Python 交互式开发环境,笔记
  • [[NextCloud]] 文件同步工具
  • [[Navidrome]] 音乐文件在线串流服务
  • [[PhotoPrism]] 基于 AI 的在线照片工具
  • [[Umami]] 一个 [[Google Analytics]] 的代替方案
  • [[uptime-kuma]] 服务在线情况检测

PikaPods 的背后团队 peakford 之前就推出过 [[BorgBase]] 的备份存储服务,并且一直在贡献 Borg 的开源客户端 [[Vorta]]。

pikapods dashboard

关于收费情况,在当前测试环境是注册用户拥有一年的免费使用。之后的收费需要看具体的使用场景,另外 PikaPods 明确提到了相关的收入最后会回馈给这些开源服务的作者,分成比例大概在 10%~20% 左右。我觉的这个是我目前能想到的最好的开源社区回馈作者的方式了,像是 Amazon 那样直接将开源项目拿走的方式可能并不适合目前这类需要一定云服务基础设施的项目。如果 PikaPods 进入一个良性循环,那么我想大部分的 self-hosted 项目都可以被纳入进来。

为什么推荐 PikaPods

买一台 VPS 自己用 docker 和 docker-compose 来搭建和管理这些服务其实也非常简单,但唯一需要让我顾虑的就是安全性和数据备份。

安全性

如果完全由自己维护和更新,那么比如 log4j 这类型的大型漏洞我个人可能还会关注到,但是如果遇到没有那么严重的漏洞,极有可能造成我的 VPS 安全性问题。如果有专业的人员去管理这些服务,以及可能出现的异常,那么可能会比我个人管理强一些,毕竟我个人的精力是有限的

数据安全性

如果是我个人使用 VPS 搭建,那我所做的就是将 Docker 容器的数据 mount 到一个目录,然后定时使用 crontab 执行备份脚本,压缩并 rsync 到我的备份数据服务器上。

在 PikaPods 中,同样可以使用 SFTP,将 mount 的文件夹备份到其他服务器,不会锁定在这个平台上,使用起来也不会有后顾之忧。即使未来某一天 PikaPods 不再运维,那么也可以将数据 dump 到自己的服务器上使用 Docker 完全恢复一份一样的服务。

数据备份和存储

PikaPods 可以使用 [[SFTP]] 将数据备份出来,即使以后不再使用 PikaPods 那也只需要将数据挂载在 Docker 容器上直接使用即可。

中途遇到一点 SFTP 连接的问题,给作者反馈之后也非常快速的得到了响应,原来是我本地 SSH 配置的问题。 一定记得如果本地配置了 SSH,那么一定要记住记得使用密码,否则 SSH 会使用本地的 KEY 去尝试登录,多次错误之后可能会被服务端拒绝。

Linux 下可以使用命令登录 SFPT:

sftp -o PreferredAuthentications=password -o PubkeyAuthentication=no username@xxx.pikapod.net

简单使用总结

注册账后之后,我直接使用了我常用的 FreshRSS,在后台查看数据,我使用了 2 CPUs,2G Memory,10GB 空间,实际运行的时候只占用 2~3% CPU,内存使用在 7% 左右,空间不到 100 MB。

目前存在的问题

目前 PikaPods 只提供欧洲和美国的服务,也就是这个服务会部署到这两地的服务器上,这也就意味着当前某些地方的连接速度可能不是非常可靠。但就我个人的使用情况来看,加上代理 阅读 RSS,上传照片连接速度也还是非常不错的。平均延迟在 150ms 左右。


2022-01-28 self-hosted , pikapods , docker , container , freshrss

在线文件管理器 Filestash

[[FileStash]] 是一个在线的文件管理器,可以使用浏览器管理分布在各种服务,各种磁盘上的数据,支持包括 SFTP,FTP,S3,[[WebDAV]],[[Dropbox]],[[Google Drive]],[[Gogs]] 存储的内容。

Filestash 的目的在给存储层增加一层抽象,这使得我们可以通过一个简单的界面来管理我们所有的后端数据。

支持:

  • SFTP
  • FTP
  • [[WebDAV]]
  • [[Git]]
  • [[AWS S3]]
  • Dropbox
  • Google Drive

官网

特性:

  • 从浏览器管理各处文件
  • 支持 Org mode1
  • 灵活的分享机制
  • 视频播放器
  • 视频转码(mov, mkv, avi, mpeg 等等)
  • 图片预览
  • 图片转码 (Nikon 和 Canon 的 raw 格式)
  • 图片管理
  • 音频播放器
  • 全文检索
  • 跨网络驱动器的分享链接
  • 办公文档 (docx, xlsx 等等)
  • 移动界面友好
  • 速度快
  • 上传文件或创建文件夹
  • 支持多云存储提供商以及多协议
  • Nyan cat loader
  • 支持快速访问,频繁访问的文件夹会展示在首页
  • Emacs, VIM 和 Sublime 快捷键绑定

费用

如果自己的安装是完全无需费用的。

如果使用官方的托管,Pro 需要 50$ 一个月。如果需要更好的支持可以到官网 查看

安装

docker run --restart=always --name filetash -d -p 8334:8334 machines/filestash

或者通过 docker-compose:

version: '3'

services:
  filestash:
    image: machines/filestash
    container_name: filestash
    restart: always
    ports:
      - "8334:8334"

更加详细的配置可以参考我的 dockerfile

运行成功之后,会设置初始密码,之后访问 /admin 可以进入管理后台。

启用 Google Drive

需要获取 Google Drive API,点击 进入 管理后台。

点击 创建 OAuth 客户端 ID,

相较于同类的优点

  • 对图像支持比较友好,甚至支持 RAW 格式
  • 支持时评,可以进行转码
  • 可以进行全文检索
  • 支持与 OnlyOffice 集成

存在的问题

空间占用太多

/var/lib/docker/overlay2/

reference

  • [[AList]]

2022-01-28 selfhosted , self-hosted , self-hosting , file-manage , docker , stash , sftp , webdav

Fly.io 使用体验

Fly.io 是一个应用部署平台,和 [[Netlify]]、[[Vercel]] 不同之处在于 Fly.io 提供了数据库,这就使得在线托管一个小型动态网站成为了可能。Fly.io 是一个 [[Y combinator]] 孵化的项目

关于收费

Fly.io 是提供一定限额的免费使用额度的,他们的目标就是让小型的应用可以免费运行,而在需要扩展的时候支付一定的费用,而这笔费用也不会太昂贵。Fly.io 的应用会根据使用情况单独计费。

Fly.io 会根据单个用户或者组织计费,官方也说了,如果想要更多免费的应用,那么你可以创建多个组织。

免费限额

分类 限额 说明
VM: shared-cpu 每个月 2340 小时 可以全天候运行 3 个 256 MB 内存的共享 CPU 的 VM
Volumes 3GB 提供 3GB 永久存储
Bandwidth 160 GB/每月 根据各个地方不同分别计算 outbound 流量
Anycast IPs 无限的 IPv6, 每一个活跃的应用一个 IPv4 每一个额外的 IPv4 地址需要额外每个月 $2
Certificates 10 个活跃的证书 最多 10 个证书

亚洲和印度免费流量是 30G,美国和欧洲是 100G。

更加具体的价格可以参考官网

需要注意的是 Fly.io 需要绑定信用卡之后才能使用。

原理

Fly 根据其官网的简介可以看到其也是借助了 Docker,用户编写代码,并用其提供的工具打包成 Docker 镜像,然后部署到 Fly 的平台上,之后就是 Fly 平台处理的事情了。本质上来说 Fly 就是提供了一个平台化的容器运行时环境。

这个服务有点像是之前那篇文章介绍的 PikaPods,区别在于 Fly.io 允许用户自己编写代码部署,而 PikaPods 则是提供了现成的服务,简化了用户用命令行部署的过程。

具体的上手过程可以完全参考这篇官方的文档

几个重要的命令

每一个 Fly 应用都需要一个 fly.toml 来告诉系统如何部署这个服务。fly.toml 会通过 flyctl launch 自动生成。

然后可以通过 flyctl deploy 来部署。

查看部署的应用

通过 status 命令查看详情:

flyctl status
❯ flyctl status
App
  Name     = evhellofly          
  Owner    = personal            
  Version  = 0                   
  Status   = running             
  Hostname = evhellofly.fly.dev  

Deployment Status
  ID          = 7b99844a-c4be-5193-eac3-e5aaxxxxx3f3         
  Version     = v0                                           
  Status      = successful                                   
  Description = Deployment completed successfully            
  Instances   = 1 desired, 1 placed, 1 healthy, 0 unhealthy  

Instances
ID      	PROCESS	VERSION	REGION	DESIRED	STATUS 	HEALTH CHECKS     	RESTARTS	CREATED    
b164cc3d	app    	0      	nrt   	run    	running	1 total, 1 passing	0       	11m57s ago	

打开应用

flyctl open

reference


2022-01-26 flyio , netlify , vercel , deploy

Borg Backup 命令行增量备份工具使用

BorgBackup 是一个 Python 和 C 语言编写的命令行增量数据备份工具。

特性:

  • 高效存储
  • 加密
  • 支持多种压缩算法
    • LZ4 快,低压缩
    • ZSTD 高速低压缩、低速高压缩
    • ZLIB 中等速度,中等压缩
    • LZMA 低速 高压缩
  • 远程备份,数据可以通过 SSH 备份到远程机器
  • FUSE
  • 跨平台
  • 开源

客户端

Borg 本身是一个命令行工具,但是在 macOS 和 Linux 下可以使用 Vorta 这是一个跨平台的 GUI 客户端。

概念

BorgBackup 中有两个必须知道的概念:

  • repository, 备份仓库
  • archive 每次备份

安装

在 Debian/Ubuntu 下:

sudo apt install borgbackup -y

如果要 Python 环境,也可以使用 pip 安装:

pip install borgbackup

也可以手工安装(记得去官网获取最新版本):

wget https://github.com/borgbackup/borg/releases/download/1.0.12/borg-linux64
sudo mv borg-linux64 /usr/local/bin/borg
sudo chown root:root /usr/local/bin/borg
sudo chmod 755 /usr/local/bin/borg

验证:

borg --version
borg --help

其他更多系统的安装可以参考官网

使用

相关命令:

borg init -- 初始化一个仓库
borg create -- 创建一个archive到仓库中
borg list -- 列出所有的仓库或者某个仓库中某个archive的内容
borg extract -- 还原某个archive
borg delete -- 手动删除某个archive
borg config -- 获取或者设置某个配置

备份流程:

# 创建仓库存储目录
$ mkdir -p /tmp/backup/
# 初始化仓库
$ borg init --encryption=repokey /tmp/backup/borg_sample

初始化 repository 的时候,可以指定加密类型:

  • none 不加密
  • repokey 或 keyfile 的时候,使用 AES-CTR-256 加密
  • 其他的加密类型可以参考官网
# 创建测试备份内容
# 会被修改的文件file_change.txt,不会被修改的文件file_static.txt,二进制大文件random.dump
$ mkdir -p /tmp/data
$ cd /tmp/data
$ echo "here is the first line of file 1" >> file_change.txt
$ echo "here is the static file" >> file_static.txt
$ dd if=/dev/urandom of=random.dump bs=10M count=10
10+0 records in
10+0 records out
104857600 bytes (105 MB) copied, 0.950948 s, 110 MB/s
$
# 第一次备份
$ borg create --stats --progress /tmp/backup/borg_sample::first /tmp/data/
------------------------------------------------------------------------------
Archive name: first
Archive fingerprint: bd5ddf9ac944353bb209576c12a16652a18f866c9d033fef2eb582d288a3cff5
Time (start): Sat, 2022-01-29 10:48:07
Time (end):   Sat, 2022-01-29 10:48:07
Duration: 0.54 seconds
Number of files: 3
Utilization of max. archive size: 0%
------------------------------------------------------------------------------
                       Original size      Compressed size    Deduplicated size
This archive:              104.86 MB            105.27 MB            105.27 MB
All archives:              104.86 MB            105.27 MB            105.27 MB

                       Unique chunks         Total chunks
Chunk index:                      42                   42
------------------------------------------------------------------------------

如果不传 --stats --progress 则静默输出。

在 create 的时候可以选择使用压缩算法:

borg create --compress zstd,1 /tmp/backup/borg_sample::2022-01-20 /tmp/data/

如果不指定压缩算法,默认会使用 LZ4,速度快,压缩比率低。

# 修改备份内容,修改file_change.txt, 新增file_new.txt,新增random_2.dump
$ cd /tmp/data
$ echo "here is the second line of file 1" >> file_change.txt
$ echo "here is new file for second backup" >> file_new.txt
$ dd if=/dev/urandom of=random_2.dump bs=10M count=10
10+0 records in
10+0 records out
104857600 bytes (105 MB) copied, 0.599837 s, 175 MB/s
$
# 第二次备份
$ borg create --stats --progress /tmp/backup/borg_sample::second /tmp/data/
------------------------------------------------------------------------------
Archive name: second
Archive fingerprint: 67b7f448698a471561ff2cf5de2b571cb40ddbce3f1a23669bfbec76d291c1b6
Time (start): Sat, 2022-01-29 10:50:35
Time (end):   Sat, 2022-01-29 10:50:35
Duration: 0.51 seconds
Number of files: 4
Utilization of max. archive size: 0%
------------------------------------------------------------------------------
                       Original size      Compressed size    Deduplicated size
This archive:              209.72 MB            210.54 MB            105.27 MB
All archives:              524.30 MB            526.36 MB            210.55 MB

                       Unique chunks         Total chunks
Chunk index:                      85                  205
------------------------------------------------------------------------------

列出备份:

# 列出所有的备份
$ borg list /tmp/backup/borg_sample/
first                                Sat, 2022-01-29 10:48:07 [bd5ddf9ac944353bb209576c12a16652a18f866c9d033fef2eb582d288a3cff5]
second                               Sat, 2022-01-29 10:49:27 [6a5131bc1098d4ba46daabc6e440d6daf9211db94ac2d17893f996ce78840162]

$
# 列出第一次备份的内容
$ borg list /tmp/backup/borg_sample::first
drwxrwxr-x einverne einverne        0 Sat, 2022-01-29 10:47:39 tmp/data
-rw-rw-r-- einverne einverne 104857600 Sat, 2022-01-29 10:47:41 tmp/data/ramdom.dump
-rw-rw-r-- einverne einverne       11 Sat, 2022-01-29 10:47:11 tmp/data/file_change.txt
-rw-rw-r-- einverne einverne       12 Sat, 2022-01-29 10:47:21 tmp/data/file_static.txt
$

使用 info 获取存档信息:

borg info /tmp/backup/borg_sample/::first

恢复备份:

# 将第一次备份恢复, 查看file_change.txt内容,只包含第一次的内容
$ mkdir -p /tmp/restore/first
$ cd /tmp/restore/first
$ borg extract --list /tmp/backup/borg_sample::first
tmp/data
tmp/data/file_change.txt
tmp/data/file_static.txt
tmp/data/random.dump
$
$ cat tmp/data/file_change.txt
here is the first line of file 1
$
# 将第二次备份导出, 查看file_change.txt内容,其中包含了第二次新增加的内容
# 也包含了第一次新增的file_new.txt和random_2.dump
$ mkdir -p /tmp/restore/second
$ cd /tmp/restore/second
$ borg extract --list /tmp/backup/borg_sample::second
tmp/data
tmp/data/file_change.txt
tmp/data/file_static.txt
tmp/data/random.dump
tmp/data/file_new.txt
tmp/data/random_2.dump
$
$ cat tmp/data/file_change.txt
here is the first line of file 1
here is the second line of file 1
$
# 第一次备份是100M,第二次是200M, 但由于是增量备份的,random.dump没有改变,因此仓库的总容量只有200M
$ du -sh /tmp/backup/borg_sample/
201M	/tmp/backup/borg_sample/
$
# 删除第一次备份,恢复第二次的备份
# 可以看到再第一次和第二次备份中都有的file_static.txt和random.dump都可以恢复出来。
# 恢复出来的数据和之前恢复的数据是一样的
$ borg delete /tmp/backup/borg_sample::first
$ borg list /tmp/backup/borg_sample
second                               Tue, 2019-09-24 04:10:55 [a423a94e8a8f4352e72c0951e6a408f4f4f6d5f362518dcbcba77b9005dafa12]
$
$ mkdir -p /tmp/restore/second_back
$ cd /tmp/restore/second_back
$ borg extract --list /tmp/backup/borg_sample::second
tmp/data
tmp/data/file_change.txt
tmp/data/file_static.txt
tmp/data/random.dump
tmp/data/file_new.txt
tmp/data/random_2.dump
$
$ diff -r /tmp/restore/second /tmp/restore/second_back
$
$ cat tmp/data/file_change.txt
here is the first line of file 1
here is the second line of file 1
$
$ cat tmp/data/file_static.txt
here is the static file

查找备份和备份之间的差异,可以使用 diff 命令:

borg diff /tmp/backup/borg_sample::first second

重命名备份名:

borg rename /tmp/backup/borg_sample::first 2022-01-20

熟悉了 Borg 命令的时候之后,大部分情况下,我们可以使用 [[Borgmatic]] 来管理备份,Borgmatic 会将基础的配置,比如仓库的地址,压缩方法,源目录,passphrase 等等在一个地方进行管理,然后使用简单的命令即可执行。

Borgmatic

备份到远程

Borg 支持远程仓库,可以将数据通过 SSH 备份到任何远程主机中。

borg init user@hostname :/path/to/repo

同样使用 mountextract 的时候:

borg mount ssh://user@hostname:222/home/einverne/borg/backup /path/to/backup
borg extract ssh://user@hostname:222/home/einverne/borg/backup

2022-01-23 borg , borgbackup , backup , ssh , scp , rsync

GitHub Code Search 使用小技巧

前两天收到 GitHub Code Search 的申请通过邮件,现在可以使用 https://cs.github.com 来作为之前的搜索的代替了,从第一手直观的感受来看就是更加精准的搜索,能根据文件名,代码方法,编程语言等等来进行搜索。

这里就只简单的记录一下我的使用体验,更加详细的使用指南请参考官方文档

概念

在进入下面的使用体验之前先了解一下 GitHub Code Search 中的一些概念。

理解 Scope

在 GitHub Code Search 中可以通过 Scope 来定义搜索的范围。

Scope 在字典里面的解释也比较直观:

the range of things that a subject, an organization, an activity, etc deals with

中文一般翻译成「范围」。

GitHub 有一些约定:

  • 必须登录 GitHub 账号才可以搜索全部公开的仓库
  • 在 forks 中的代码只有当 stars 数超过父仓库时才会被列入索引,当需要搜索 star 数超过父项目的仓库时,需要使用 fork:true 或者 fork:only 参数。更多可以参考如何搜索forks
  • 只有默认的分支会被索引
  • 只有小于 384KB 的文件会被索引
  • 只有小于 500000 个文件的仓库能被搜索
  • 只有在过去一年中有活动的,或者在搜索结果中有记录的仓库才能被搜索
  • 除了 filename 的搜索,必须至少有一个关键字才能搜索,比如,搜索 language:javascript 不是合法的,只有 amazong language:javascript 才是合法的
  • 搜索结果中只会显示同一个文件的两个片段,但是有可能在文件中会存在更多的符合结果的内容
  • 搜索中不能包含

      . , : ; / \ ` ' " = * ! ? # $ & + ^ | ~ < > ( ) { } [ ] @
    

qualifiers

Code Search 中提供了一些修饰语语法,可以用来对搜索结果做限定。

  • 限定在某仓库中 (eg. repo:github/primer)
  • 限定在组织中 (eg. org:github 或者 user:colinwm)
  • 限定语言 language:python
  • 限定文件路径 path:README.md
  • Symbol qualifier symbol:scanbytes
  • 限定内容 content:hello

正则

Code Search 还支持使用正则表达式来搜索:

/git.*push/

正则表达式需要使用 / 作为范围,上面的搜索词就会搜索所有以 git 开头 push 结束的内容。

记住如果要在其中使用 / 那么需要进行转义,比如搜索目录 App/src

/^App\/src\//

正确匹配

正常情况下搜索 hello world 相当于搜索 hello AND world 这两个词可能不连在一起,如果要精确地查找搜索词,可以使用双引号:

"hello world"

Boolean operations

Code search 支持几种常用的搜索连接词:

  • AND
  • OR
  • NOT

可以使用括号来改变优先级:

(language:ruby OR language:python) AND NOT path:"/tests/"

可以点击这里加入到 waitlist

使用

搜索样例

过去几天我最常用的就是搜索学习别人是如何写 docker-compose.yml 文件的,因为最近在学习 Traefik 入门使用 所以把历史上用 Nginx-proxy 反向代理的一些服务重新配置了一下。因为 Traefiki 的配置语法略微复杂,我先阅读了一遍 Traefik 官网的文档,了解了一些基础概念,然后因为官网没有整体配置的一个样例,我就觉得直接看完整的项目配置比较快,所以直接用 Code Search 搜索一些完整的配置进行学习。

比如把 [[Vaultwarden]],[[NextCloud]] 等,这个时候我就使用搜索语法:

bitwarden path:docker-compose.yml
nextcloud path:docker-compose.yml

搜索出来一些结果然后学习,然后配置的过程中还发现了不少很好的项目。

搜索配置

之前在配置 ArchiveBox 服务的 ArchiveBox.conf 的时候,直接搜索该文件直接可以找到对应的官网仓库的样例配置,依照样例配置进行自己的修改。

关键字搜索

我常用的另外一个比较多的场景就是搜索错误代码或者错误描述,常常在 IDE 中当然也能搜索,但是有些大型的库常常我本地没有索引所以搜索起来可能比较慢,这个时候拿到错误直接到界面搜索,反而可以更快的定位到问题。这个时候只需要限定仓库的位置,然后加上错误描述即可。

reference


2022-01-21 github , code , code-search

小米平板 5 Pro 初体验及设置

年初的时候去线下做了一下体验,觉得小米平板 5 在影音和阅读方面还能胜任,所以就购入了一台小米平板 5 Pro,日常可能就用来阅读 PDF 和用来看视频。

选购思路

为什么买 Android 平板?

因为我重度使用的应用,比如 [[Syncthing]], [[Obsidian]], [[静读天下 Moon+Reader]] 等等在 Android 下运行良好,我也不需要 iPad 那些独占的功能。

而且 Android 的开放性比较好,安上 Termux,甚至能够在 Android 环境下使用 Linux ,简单的 ssh 命令也可以瞬间让平板成为一个连接远程服务器的利器。

小米平板对比三星,联想平板?

说实话在没有体验小米平板 5 之前,我一直观望的是三星的平板,毕竟在那几年里面,Android 平板几乎消失,在这两年 iPad 生态逐渐强大,各大 Android 厂商才又将 Android 平板拿起来,但 Android 平板和 iOS 的差距很快就被系统的扩展性赶上了,虽然应用的适配和兼容性可能无法赶上 iPad,一些精品的应用体验,比如书写,绘画可能也无法短时间内追赶上 iPad,但是在体验了一番 MIUI 之后,感觉小窗模式,分屏模式还是稍微超出了我的预期,所以,想买过来深度再体验一下。

小米平板 5 对比 5 Pro 版本?

在硬件方面,

  • Pro 版本采用 870 芯片,略强于 860
  • 扬声器方面,内置八个扬声器,外加杜比音效,好过 5 的四个扬声器
  • 运行内存,Pro 版本 LPDDR5+UFS 3.1,普通版本 LPDDR4x+UFS 3.1,但这一点差距似乎对整体影响并不突出
  • 后置摄像头,Pro 版本后置双摄1300万像素+500万景深镜头,5 只有单摄 1300 万像素,不过好像我也不会拿平板去拍照,这个不太重要
  • Pro 支持蓝牙 5.2,普通版本只支持蓝牙 5.0
  • 充电方面,Pro 支持 67W 快充,5 默认带 33W 充电
  • Pro 版本带有指纹解锁
  • Pro 版本电池 8600 毫安,而 5 略微大一些,为 8720 毫安

而二者的屏幕都是一块 11 英寸的 IPS LCD,带 120Hz 的刷新率,分辨率是 1600*2560.

Pro 版本多出了一个指纹解锁,CPU 更好一些,我愿意为这点升级补差价。

Termux 初始化

之前就已经知道 Termux 可以在 Android 上模拟出一套 GNU/Linux 环境,所以直接更新一套初始化脚本到我的 dotfiles

配件

小米平板 5 Pro 自带的两个配件有一只笔和一个键盘,当时买完就脑袋一发热买了一个键盘,虽然日常还是会用到,但感觉似乎任何一个蓝牙键盘都可以代替,除了便携性好一些之外没有太多想说的。键盘的手感也只是能用而已。

笔的话,我没有购买,因为我觉得不会在这个平板上面来写字做笔记,如果是看 PDF 的需求,我还有 Boox Note 2 ,自带的笔已经够用了。


2022-01-18 xiaomi , xiaomi-pad , xiaomi-pad-5-pro , android , termux , pad

认识 Linux 下 btmp 日志文件

查看 VPS 日志的时候发现 /var/log/ 下存在一个 100M+ 大小的 btmp 文件,我知道 /var/log 目录下一般都是 Linux 系统的日志存放路径,通常 auth.log 会记录登录相关的日志,其他的 Nginx,PHP,dpkg,syslog 等等都比较熟悉,唯一没见过的就是 btmp 文件。所以简单记录一下。

btmp 文件也是日志文件,不过仅仅记录失败的登录。这也就意味着有人尝试暴力登录我的服务器。

和 btmp 相关的日志文件还有两个:

  • utmp 文件记录用户登录信息,包括用户登录的终端,登出状态,系统时间,当前系统的状态,系统启动的时间(被 uptime 命令使用)等等
  • wtmp 会记录 utmp 文件的历史记录,包括了当前登录用户信息和历史用户登录信息

以上三个文件都是二进制数据。

查看 btmp 文件

btmp 文件不是一个纯文本的文件,所以不能直接使用 less, cat 查看,需要借助 last 命令:

last -f /var/log/btmp
last -f /var/log/wtmp
last -f /var/log/utmp

如果直接执行 last 不带任何参数,则会展现用户什么时候登录,什么时候登出的。

也可以使用 lastb 命令,默认会读取 /var/log/btmp 文件。

另外也可以使用 utmpdump 命令将二进制文件转成文本文件查看。

utmpdump /var/log/btmp

遇到 btmp 文件过大的情况下的安全措施

上文提到过 btmp 只会记录失败的登录,如果这个文件增长很快那么也就意味着有人在不断尝试登录,可能就是在暴力尝试,在上面的日志文件中也能看到很多 root 尝试登录,也有很多默认的用户在不停尝试。这个时候就需要特别注意一下系统的安全。

通常情况下,在刚初始化系统的时候这些安全措施就需要补全。

通常在配置了 [[fail2ban]] 之后就会好很多了。

reference


2022-01-17 linux , log , btmp , fail2ban , security , vps

在线数据泄漏查询网站

have i been pwned

have i been pwned? 是一个提供了查询电子邮件、电话号码、密码等是否被泄漏的在线网站。该网站提供了过去几十年中的各大数据泄漏事件。用户注册账户之后,可以在数据被泄漏的第一时间收到提醒。

这一次 Twitter 的 2 亿多条数据泄漏,包括邮箱,用户名,手机号等,就是 have i been pwned 第一事件发送了提醒。

Firefox Monitor

Firefox Monitor 是由 Mozilla 开发的,在 Firefox 上提供的一项服务,可以帮助用户检查电子邮件或者密码有没有被泄漏。

在网站上输入电子邮箱地址,Firefox Monitor 会在自己的数据库中查询历史上曾经发生的数据泄露事件中有没有泄漏查询的数据,对于保护用户个人的网络安全非常有用。


2022-01-06 data-breach , data-leak , security

在 Obsidian 中集成 GPT-3 提高输入效率

前两天在 Twitter 上发了一个贴子,说如果 [[Obsidian]] 中能继承 [[ChatGPT]] 和 [[GitHub Copilot]] 就好了,我想来虽然也可以在 IntelliJ 和 VSCode 中打开本地的笔记仓库,但是一个礼拜前我尝试了一下用 VSCode 打开,竟然比 Obsidian 还卡,不知道哪里除了问题,所以只能再切换回 Obsidian。好在发帖没多久就发现了 Text Generator 这个插件,用 GTP-3 的 API 驱动的文字生成,并且在调研的过程中又还发现了 Obisidain 下不少能提高输入效率的工具,这里就一切总结一下。

文本生成

使用 Text Generator 生成文本

  • 在 Obsidian 下安装 Text Generator 插件
  • 获取 OpenAI API Key
    • 登录 OpenAI 官网,点击 Account,然后点击 View API keys,或者直接访问 OpenAI API key
  • 使用 cmd+j 快捷键

使用方式

  • 第一种方式,在记笔记的过程中,使用快捷键 cmd+j,让 Text Generator 续写后文内容。
  • 第二种方式是使用左侧边栏上的按钮

文本扩展

Text Expander 类的工具是将用户的输入自动扩展成一个更长的内容,通常用来快速输入某些内容。因为我已经有了很多方法来实现 Text Expander(文本扩展),就没有使用 Obsidian 中的插件。

我个人使用的文本扩展方法主要有两个:

这两个工具一直都秉持我的理念,开源,跨平台,并且可以通过文本的方式配置。

RIME

RIME 是中州韻輸入法引擎 (Rime Input Method Engine) 的缩写,由 RIME 扩展出了不同平台上的输入法,小狼毫,中州韵,鼠须管等等,在 RIME 中可以配置自定义词库,然后在输入法中,通过自定义的映射来实现快速输入。

比如在自定义短语中配置:

MySQL   mysql   100
我看下  wkx     30

就可以实现在输入 mysql 的时候自动修正为 MySQL,在输入 wkx 的时候扩展成 我看下。通过进阶的 lua 脚本也可以实现输入 date 自动扩展成当前日期等等。

Espanso

Espanso 是一款是 Rust 编写的跨平台的 Text Expander。Espanso 可以通过纯文本配置 来设定文本的扩展。

espanso demo

比如演示中输入 :date 自动扩展成日期。为了防止误扩展,一般都会在缩略词前面加上冒号。

  • [[HuggingFace]]

reference


2022-01-03 obsidian , text-generator , gpt-3 , openai , chatgpt , github-copilot

Logseq 第一次试用记录以及发布 Logseq 到网页

早之前在使用 [[Obsidian]] 的时候就有了解过 [[Logseq]] 但一直没有找到机会去尝试一下,毕竟我从 [[WizNote]] 迁移到 Obsidian 之后使用一直没有遇到任何问题,毕竟 Obsidian 够简单,也足够扩展性,并且基于 Markdown 文件的笔记是我过去一直在使用的方式。但现在让我有尝试使用一下 Logseq 的契机是因为在以前我都是使用 Vault 存放所有的笔记,然后使用其中一个 Blog 目录存放我想发布的内容,这样每一次我想发布一个具体的文章的时候就可以直接将文件移动到 Blog/_posts 目录之下,然后 Git 提交即可,但这个发布存在的问题便是其中的特殊双向链接 [[]] 会在页面上有些违和,而我看到 Logseq 可以将页面直接以 HTML 方式发布,并且也可以非常好的处理双向链接的问题,于是想来试一试。

Logseq 官方的文档 便是一个非常好的例子,展示界面几乎和用户的编辑页面是一致的,在线浏览也没有任何卡顿的情况。

Logseq 和 Obsidian 存在的区别

block

上手体验的第一个非常大的区别就在于 Logseq 有 block 的概念,这个概念可能是从 Roam Research 中借用而来,不像 Obsidian 整个文档就是一个 markdown 文件,所以每一行文字其实还是段落,但是 Logseq 中每一次 “Enter” 都创建了一个 block。Logseq 中使用 ((uuid)) 的语法来引用 block。有了 block 的概念之后就会发现其实文档内容的最小单元变成了 block,而在 Obsidian 中我能使用的最小单元也无非是通过 # 来划分出来的页面的段落。这可能是 Logseq 更加灵活的地方,但因为目前我还没有想好怎么使用这个 block 所以之后有了具体的使用场景再来分享。

command

Obsidian 中的 Command 和 Logseq 中的 Command 在使用起来还有一些区别,我设定了 Ctrl + P 来调用 Obsidian 中的 Command Palette,而这其中的命令大部分是对整个文档,或者部分内容进行的调整。而在 Logseq 中,在任何页面中使用 / 都可以进行响应的插入,/ 更像是 Notion 的方式,通过 / 来快捷调用复杂的输入操作,比如插入页面引用、块引用、标题、图片等等。

但我个人觉得在 / 中提示输入标题有些累赘,我个人的习惯一般不会在一篇文章中使用三级标题以上的子标题,那这也就意味着我只会使用 1~3 个 #,那么在纯 markdown 文档中,输入 # 要远比先输入 / 然后搜索对应的标题,选中要来的快,即使是输入三个 # 也会比 / 快。

/ 让我觉得最重要的就应该是页面引用和块引用了,通过模糊搜索,在笔记和笔记之间建立关系使用 / 就大大简化的。而在 Obsidian 中我就只能使用 [[ 来进行页面的关联。

vim mode

Obsidian 让我直接上手的一个非常重要的原因就是开箱支持的 Vim 模式,我几乎没有想就启用了,并且一直使用到现在,这无非只是让我在终端的笔记转移到了 Obsidian,并且我熟悉而这个快捷键,命令都可以直接使用,这也让我在终端,IntelliJ IDEA,浏览器 Vimium 达成了统一。而 Logseq 开箱就是所见即所得的界面,当然普通使用起来是没有问题的,但用起来就慢慢地发现有些别扭,比如在上一行插入,或者快速跳转到页尾,以前非常熟悉的 O 或者 G 突然没有了就有些陌生。

然后再看到 Logseq 的 Feature Request ,大家对 Vim-mode 的讨论,要求支持还是挺多,不过截止目前还用不了。

分享

就像上面提到的一样,让我试用 Logseq 最重要的一个原因就是 Logseq 生成在线文档的能力,因为我之前使用 Jekyll 的文档分享部分 Obsidian Vault 中的内容就没有购买 Obsidian Publish 服务,因为一来我觉得 Jekyll 够用,然后 Obsidian Publish 服务的页面最初的时候访问优点慢,并且早鸟价 8$ 一个月的价格也有些高。但后来在使用的过程中还是会有一些些的不便,毕竟双向链接如果没有特殊的处理会显得有些奇怪。

Tag 使用

在 Logseq 中使用 #tag 新建 tag,当点击 tag 的时候会创建新的页面,而在 Obsidian 中 #tag 就只是页面的一个元数据,标签。在 Logseq 中可以点击 tag 页面来查看所有该标签下的页面和块,而在 Obsidian 中我通常是使用搜索。

Logseq 中特殊的语法

Logseq 中使用 key:: value 格式来对页面或块进行属性设置,页面的属性在页面的第一个块定义,作为 frontmatter,块属性可以在任何块中定义。

Logseq 中的 Properties 的两大作用:

  • Query,可以通过查询语法来将带有 property 的内容检索出来
  • 定义 Page/Block 的通用属性,比如想要有一个模板,当记录一本书的时候自动会有相应的属性

Obsidian 搭配 Logseq 使用

在上面的使用过程中,我一直使用 Git 来追踪 Logseq 界面中修改了文档之后在原始文档中的体现,大体来看如果没有使用 Logseq 自身的特殊语法,大致还是兼容 markdown 语法的。

所以我想到了如果将 Logseq 仓库存放在 Obsidian Vault 中,那么其实和我之前使用 Jekyll 发布内容的方式就是一致的了,我只需要把需要发布的内容移动到 Logseq 文件夹下即可。比如说我的 Logseq 仓库叫做 notes,那么他下面会有一个 pages 文件夹,存放的都是 Logseq 中的笔记原始文件。那么我将整个 notes 作为我 Obsidian Vault 的一部分,那么我既可以在 Obsidian 中编辑这些笔记,也可以用 Logseq 打开这个子文件夹来编辑。我只需要使用 Logseq 兼容的语法,那么每一次提交,然后推送到 GitHub 之后,就可以利用 GitHub Actions 自动发布。

Obsidian Vault 是一个独立的仓库,然后使用 git submodule 将 Logseq 仓库添加到其中,还可以利用版本控制来管理。

将 Logseq 发布到 GitHub Pages

这里使用 pengx17 的 Logseq-publish 的 GitHub Action,在个人仓库下创建 .github/workflows/main.yml 文件,根据自己的情况填入配置:

name: CI

# Controls when the workflow will run
on:
  push:
    branches: [master]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2
      - name: Logseq Publish
        uses: pengx17/logseq-publish@main
      - name: add a nojekyll file
        run: touch $GITHUB_WORKSPACE/www/.nojekyll
      - name: Deploy
        uses: JamesIves/github-pages-deploy-action@v4
        with:
          branch: gh-pages # The branch the action should deploy to.
          folder: www # The folder the action should deploy.
          clean: true
          single-commit: true

然后每一次 push 之后会自动触发 build,将静态 HTML 文件发布到 gh-pages 分支中。然后在 GitHub 仓库设置界面 Pages 中设置域名即可。

我发布的内容 https://notes.einverne.info


2022-01-03 logseq , notes , backlink , markdown

电子书

本站提供服务

最近文章

  • Dinox 又一款 AI 语音实时转录工具 前两天介绍过 [[Voicenotes]],也是一款 AI 转录文字的笔记软件,之前在调查 Voicenotes 的时候就留意到了 Dinox,因为是在小红书留意到的,所以猜测应该是国内的某位独立开发者的作品,整个应用使用起来也比较舒服,但相较于 Voicenotes,Dinox 更偏向于一个手机端的笔记软件,因为他整体的设计中没有将语音作为首选,用户也可以添加文字的笔记,反而在 Voicenotes 中,语音作为了所有笔记的首选,当然 Voicenotes 也可以自己编辑笔记,但是语音是它的核心。
  • 音流:一款支持 Navidrom 兼容 Subsonic 的跨平台音乐播放器 之前一篇文章介绍了Navidrome,搭建了一个自己在线音乐流媒体库,把我本地通过 [[Syncthing]] 同步的 80 G 音乐导入了。自己也尝试了 Navidrome 官网列出的 Subsonic 兼容客户端 [[substreamer]],以及 macOS 上面的 [[Sonixd]],体验都还不错。但是在了解的过程中又发现了一款中文名叫做「音流」(英文 Stream Music)的应用,初步体验了一下感觉还不错,所以分享出来。
  • 泰国 DTV 数字游民签证 泰国一直是 [[Digital Nomad]] 数字游民青睐的选择地,尤其是清迈以其优美的自然环境、低廉的生活成本和友好的社区氛围而闻名。许多数字游民选择在泰国清迈定居,可以在清迈租用廉价的公寓或民宿,享受美食和文化,并与其他数字游民分享经验和资源。
  • VoceChat 一款可以自托管的在线聊天室 VoceChat 是一款使用 Rust(后端),React(前端),Flutter(移动端)开发的,开源,支持独立部署的在线聊天服务。VoceChat 非常轻量,后端服务只有 15MB 的大小,打包的 Docker 镜像文件也只有 61 MB,VoceChat 可部署在任何的服务器上。
  • 结合了 Google 和 AI 的对话搜索引擎:Perplexity AI 在日本,因为 SoftBank 和 Perplexity AI 开展了合作 ,所以最近大量的使用 Perplexity ,这一篇文章就总结一下 Perplexity 的优势和使用技巧。