Framist's Little House

◇ 自顶而下 - 面向未来 ◇

0%

建站实践

建站杂记:framist.top

乱七八糟地记录建站、博客等等的配置

实时更新

临时的主页

用 typora 随便写了一下

备案

早知道备案这么麻烦就租香港或国外的的服务器了

浙 ICP 备 2022002862 号 -1

网站安全与运维

一些安全的注意事项:

treehollow/install-doc: 如何搭建一个树洞 (github.com)

请务必确保时刻没有子域名 DNS 解析到服务器真实 IP,并且服务器真实 IP 必须始终保密!

服务器的 IP 如果泄露,DDoS 等情况就有可能发生,同时还会极大地增加攻击面。因此,服务器的 HTTP 流量必须始终通过 CDN(比如 Cloudflare CDN)。在 https://securitytrails.com/dns-trails 网站上,一个域名的全部子域名和 DNS 历史记录都可以轻松查到,因此不能有任何时刻让服务器真实 IP 暴露在外。

配置 SELinux

但由于目前使用的个人主站的服务器 ip 早已暴露,所以先没有做这些安全事项了

SSH

用公钥登录:ssh-keygenssh-copy-id 目标@服务器 即可

nginx

配置文件

/etc/nginx/sites-available/ 下的配置文件

default add:

1
2
3
4
5
6
7
8
# Redirect www to non-www
server {
listen 80;
listen [::]:80;
server_name www.framist.top;

return 301 $scheme://framist.top$request_uri;
}

craft.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
# my app -- wordpress 's conf
# ln -s /etc/nginx/sites-available/craft.conf /etc/nginx/sites-enabled/craft.framist.top.conf

server {
server_name craft.framist.top;
client_max_body_size 50m;
location / {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

md.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
# my app -- CodiMD 's conf
# ln -s /etc/nginx/sites-available/md.conf /etc/nginx/sites-enabled/md.framist.top.conf

server {
server_name md.framist.top;
client_max_body_size 50m;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

safc.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# my app -- safc 's conf
# ln -s /etc/nginx/sites-available/safc.conf /etc/nginx/sites-enabled/safc.framist.top.conf
server {
server_name safc.framist.top;
client_max_body_size 50m;
location / {
proxy_pass http://127.0.0.1:11096;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

siyuan.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# my app -- siyuan 's conf
# ln -s /etc/nginx/sites-available/siyuan.conf /etc/nginx/sites-enabled/sy.framist.top.conf
server {

server_name sy.framist.top;
client_max_body_size 50m;
location / {
proxy_pass http://127.0.0.1:6806;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 配置 WebSocket 反代 `/ws`
location /ws {
proxy_pass http://127.0.0.1:6806;
proxy_read_timeout 60s;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'Upgrade';
}
}

/etc/nginx/sites-enabled/ 下的配置文件

1
2
3
4
5
lrwxrwxrwx 1 root root   37 Aug 25  2023 craft.framist.top.conf -> /etc/nginx/sites-available/craft.conf
lrwxrwxrwx 1 root root 34 Jan 26 2022 framist.top.conf -> /etc/nginx/sites-available/default
lrwxrwxrwx 1 root root 34 Aug 25 2023 md.framist.top.conf -> /etc/nginx/sites-available/md.conf
lrwxrwxrwx 1 root root 36 Sep 25 2023 safc.framist.top.conf -> /etc/nginx/sites-available/safc.conf
lrwxrwxrwx 1 root root 38 Jan 19 2022 sy.framist.top.conf -> /etc/nginx/sites-available/siyuan.conf
以一个脚本实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/bin/bash
# filepath: setup_nginx_config.sh

# 确保以 root 权限运行
if [ "$EUID" -ne 0 ]; then
echo "请以 root 权限运行此脚本"
exit 1
fi

# 创建配置目录
cd /etc/nginx/sites-available/

# 创建 default 配置
cat >> default << 'EOF'
# Redirect www to non-www
server {
listen 80;
listen [::]:80;
server_name www.framist.top;

return 301 $scheme://framist.top$request_uri;
}
EOF

# 创建 craft.conf
cat > craft.conf << 'EOF'
# my app -- wordpress 's conf
server {
server_name craft.framist.top;
client_max_body_size 50m;
location / {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
EOF

# 创建 md.conf
cat > md.conf << 'EOF'
# my app -- CodiMD 's conf
server {
server_name md.framist.top;
client_max_body_size 50m;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
EOF

# 创建 safc.conf
cat > safc.conf << 'EOF'
# my app -- safc 's conf
server {
server_name safc.framist.top;
client_max_body_size 50m;
location / {
proxy_pass http://127.0.0.1:11096;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
EOF

# 创建 siyuan.conf
cat > siyuan.conf << 'EOF'
# my app -- siyuan 's conf
server {
server_name sy.framist.top;
client_max_body_size 50m;
location / {
proxy_pass http://127.0.0.1:6806;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /ws {
proxy_pass http://127.0.0.1:6806;
proxy_read_timeout 60s;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'Upgrade';
}
}
EOF

# 创建软链接
cd /etc/nginx/sites-enabled/
ln -sf ../sites-available/craft.conf craft.framist.top.conf
ln -sf ../sites-available/default framist.top.conf
ln -sf ../sites-available/md.conf md.framist.top.conf
ln -sf ../sites-available/safc.conf safc.framist.top.conf
ln -sf ../sites-available/siyuan.conf sy.framist.top.conf

# 设置权限
chmod 644 /etc/nginx/sites-available/*

# 测试配置
nginx -t

# 如果测试成功,重启 Nginx
if [ $? -eq 0 ]; then
systemctl restart nginx
echo "Nginx 配置已更新并重启"
else
echo "Nginx 配置测试失败,请检查配置文件"
exit 1
fi

Cloudflare: 免费 CDN 加速 & 保护

需要修改域名服务器,国内用户访问速度不稳定

HTTPS - SSL

可以非常方便地使用

Let's Encrypt

实现 (通过 Certbot 的脚本)

真的真的非常地方便!并且免费!所以我不写具体教程了。

一些具体的细节需要注意,比如有些后端的应用需要端口转发等。

SEO

  • Google:search-console
  • Bing:
  • Baidu:

所有权认证:

阿里云 DNS 添加 TXT 记录方法:在 DNS 解析设置中为主机记录 @ 添加 TXT 记录,记录值为 google-site-verification=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

hexo 添加 HTML <meta> 标记方法:可以在 themes/主题名称/layout/_partials/head.swig 中编辑添加 Google 提供的用于认证 HTML 代码。

Clash

2025:mihomo

旧的方法:

采取 docker 配置的方法

官方文档:Clash 服务运行 | Clash (a76yyyy.github.io)

参考:如何在 Linux 上优雅的使用 Clash? · Zs’s Blog (zzsqwq.cn)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
version: "3"
services:
clash:
image: dreamacro/clash
container_name: clash
volumes:
- ./config.yaml:/root/.config/clash/config.yaml
- ./Country.mmdb:/root/.config/clash/Country.mmdb
- ./ui:/ui # dashboard volume
ports:
- "7890:7890"
- "7891:7891"
- "9090:9090" # external controller (Restful API)
restart: unless-stopped
network_mode: "bridge"

Note. 在 config.yaml 中:allow-lan: true。不然的话没法用 docker clash 做转发。

ui 可以可以直接访问对应的链接

记得保护好端口,仅限本地环回或临时使用

网站应用

我的愿景是所有数据与计算都在云端。无论何时何地,只需一台安装有通用浏览器的终端机,就能安全方便地访问自己的应用与数据

frp

无需 root 权限

n2n

二层 VPN,需要 root 权限,广泛平台支持,包括 openwrt

tailscale

这个是打洞最佳选择,需要 root 权限,需要登陆

SAFC

/etc/systemd/system/safc-bot.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Unit]
Description=SAFC Bot Service
After=network.target

[Service]
Environment="https_proxy=http://127.0.0.1:7890"
Environment="http_proxy=http://127.0.0.1:7890"
Environment="TELOXIDE_TOKEN=<your_token>"
Environment="TELOXIDE_PROXY=http://127.0.0.1:7890"
Environment="SAFC_DB_PATH=/root/Services/SAFC/db.sqlite"
ExecStart=/root/Services/SAFC/safc_bot
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

思源笔记

docker 部署思源

配置 docker-compose.yml 文件,开启 HTTPS 后可设置 --ssl=true

docker-compose up -d (2025 了,使用 docker compose) 后台启动容器

一个简单的手动更新 python 脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/usr/bin/python3
import os
v = input('please enter your siyuan version: v')
print(f'upgrade to v{v}')

assert os.system(f'docker pull b3log/siyuan:v{v}') == 0

d_c = f'''
version: '3'

services:
siyuan:
image: b3log/siyuan:v{v}
container_name: siyuan
restart: always
environment:
- PUID=1000
- PGID=1000
# user: "1000:1000"
ports:
- "6806:6806" # 宿主机端口:容器端口
volumes:
- /root/Services/siyuan/workspace:/siyuan/workspace # workspace 是思源的数据目录
command: [--ssl=true,--accessAuthCode=<your_code>,--workspace=/siyuan/workspace/ ]

'''
with open('./docker-compose.yml', 'w') as d:
d.write(d_c)

# 停止删除容器
os.system('docker-compose down')
# 重新启动容器
os.system('docker-compose up -d')
[点击查看旧版本的方法]

2.4 版本之前

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
version: "3"

services:
siyuan:
image: b3log/siyuan:latest
container_name: siyuan
restart: always
user: "1000:1000" # 镜像中是使用默认创建的普通用户 `siyuan` 来启动内核进程的
ports:
- "6806:6806" # 宿主机端口:容器端口
volumes:
- /root/siyuan/workspace:/siyuan/workspace # workspace 是思源的数据目录
command: [
--resident=true,
--ssl=false,
--accessAuthCode=password,
--servePath=sy.framist.top,
--workspace=/siyuan/workspace/,
] # 约 2.4 版本前

约 2.4 版本后 但仍然是旧方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
version: "3"

services:
siyuan:
image: b3log/siyuan:latest
container_name: siyuan
restart: always
user: "1000:1000" # 镜像中是使用默认创建的普通用户 `siyuan` 来启动内核进程的
ports:
- "6806:6806" # 宿主机端口:容器端口
volumes:
- /root/siyuan/workspace:/siyuan/workspace # workspace 是思源的数据目录
command:
[
--ssl=false,
--accessAuthCode=password,
--servePath=sy.framist.top,
--workspace=/siyuan/workspace/,
]

镜像中是使用默认创建的普通用户 siyuan(uid 1000/gid 1000)来启动内核进程的,所以在宿主机创建工作空间文件夹时请注意设置该文件夹所属用户组:chown -R 1000:1000 ./workspace,在启动容器时需要带参数 -u 1000:1000

使用 watchtower 优雅得更新 docker 镜像:TODO 还未实际测试

docker-compose.yml 后添加:

1
2
3
4
5
6
7
8
9
watchtower:
image: containrrr/watchtower
container_name: watchtower_for_siyuan
restart: always
environment:
- TZ=Asia/Shanghai
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: siyuan --cleanup --schedule "0 0 5 * * *" # 北京时间早晨 5 点

Nginx 反向代理

Nginx 多个子域名映射到不同的端口或 ip

https://cloud.tencent.com/developer/article/1558240

注意要在阿里云的 DNS 云解析设置中添加子域名解析记录,否则反向代理不生效。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# cp nginx_siyuan.conf /etc/nginx/sites-available/siyuan.conf
# ln -s /etc/nginx/sites-available/siyuan.conf /etc/nginx/sites-enabled/sy.framist.top.conf
server {
listen 80;

server_name sy.framist.top;

location / {
proxy_pass http://127.0.0.1:6806;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 配置 WebSocket 反代 `/ws`
location /ws {
proxy_pass http://127.0.0.1:6806;
proxy_read_timeout 60s;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'Upgrade';
}
}

数据同步、备份与还原

备份与还原

新版本可以直接通过 思源-设置-导出 进行备份与还原。以下是旧版本的方法:

旧版本的方法备份与还原
1
2
3
4
5
6
7
8
# tar:
# -z 代表用 gzip 算法来压缩/解压。
# -c, --create 创建一个新归档
# -v:显示所有过程
# -f, --file=ARCHIVE 使用归档文件或 ARCHIVE 设备
tar -zcvf siyuan_backup.tar.gz [思源的数据目录]
# sz 从服务器下载到本地
sz siyuan_backup.tar.gz

上传备份文件

1
2
3
4
5
# rz 上传文件到服务器
rz
# 注:z 代表用 gzip 算法来压缩/解压。
# -x, --extract, --get 从归档中解出文件
tar -zxvf [原文件名].tar.gz

2.5.0 版本之后的第三方数据同步(官方)

思源笔记 v2.5.0 发布,数据同步和备份支持第三方 WebDAV 和 S3 协议,支持导出长图 之后,就可以官方支持第三方数据稳定的同步了

仿照用阿里云 OSS 建图床的方式(这个有很多教程了)

阿里云创建一个对象 OSS(私有读/写)

在 RAM 访问控制中创建一个子用户

开通 Open API 调用访问,记下 AccessKey IDAccessKey Secret

在 思源 - 设置 - 云端 里选择 S3,填入以下内容

bucket 实际上就是 阿里云上的名字

Endpoint(地域节点)

Region 公共云下 OSS Region 和 Endpoint 对照表

Addressing 选择 Virtual-hosted-style (?)

注意内网可以使用内网访问节点

然后就可以同步啦

哎,现在这个又成收费功能了。其实这种不需要开发者提供支持服务,软件本身又是开源的情况下,做成必须登录才使用的功能是不合适的,而且很容易就绕过、产生分叉

code-server

HedgeDoc

todo

Codimd

旧的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
version: "3"
services:
database:
image: postgres:11.6-alpine
environment:
- POSTGRES_USER=codimd
- POSTGRES_PASSWORD=change_password
- POSTGRES_DB=codimd
volumes:
- "database-data:/var/lib/postgresql/data"
restart: always
codimd:
image: hackmdio/hackmd:2.4.1
environment:
- CMD_DB_URL=postgres://codimd:change_password@database/codimd
- CMD_USECDN=false
depends_on:
- database
ports:
- "3000:3000"
volumes:
- upload-data:/home/hackmd/app/public/uploads
restart: always
volumes:
database-data: {}
upload-data: {}

备份:

1
2
3
cd /var/lib/docker/volumes
tar -zxvf plasma_backup.tar.gz

新的:

1
2
3
cd /var/lib/docker/volumes
tar -zcvf plasma_backup.tar.gz

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
version: "3"
services:
database:
image: postgres:11.6-alpine
environment:
- POSTGRES_USER=codimd
- POSTGRES_PASSWORD=change_password
- POSTGRES_DB=codimd
volumes:
- "database-data:/var/lib/postgresql/data"
restart: always
codimd:
image: hackmdio/hackmd:2.5.4
environment:
- CMD_DB_URL=postgres://codimd:change_password@database/codimd
- CMD_USECDN=false
depends_on:
- database
ports:
- "3000:3000"
volumes:
- upload-data:/home/hackmd/app/public/uploads
restart: always
volumes:
database-data: {}
upload-data: {}

再新:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
version: "3"
services:
database:
image: postgres:11.6-alpine
environment:
- POSTGRES_USER=codimd
- POSTGRES_PASSWORD=change_password
- POSTGRES_DB=codimd
volumes:
- "database-data:/var/lib/postgresql/data"
restart: always
codimd:
image: nabo.codimd.dev/hackmdio/hackmd:2.5.4
environment:
- CMD_DB_URL=postgres://codimd:change_password@database/codimd
- CMD_USECDN=false
depends_on:
- database
ports:
- "3000:3000"
volumes:
- upload-data:/home/hackmd/app/public/uploads
restart: always
volumes:
database-data: {}
upload-data: {}

Hexo

个人博客部分目前是用 Hexo - Next 建设的。

配置备份

配置多端发布

插件

参考:「推荐」本站用到的 hexo 插件 | 若风 (loafing.cn)

Hexo 如何隐藏文章

使用的插件:

  • hexo-abbrlink 用于更好的 URL
  • hexo-pangu
  • hexo-broken-links-checker 检查文章中的链接是否失效

602 雏鹰之家

602.framist.top

bucket 静态网页托管

注意事项:

出于安全考虑,中国内地各地域自 2018 年 09 月 28 日起,非中国内地各地域自 2019 年 09 月 25 日起,通过浏览器访问 OSS 静态网页类型文件(mimetype 为 text/html,扩展名包括 HTM、HTML、JSP、PLG、HTX、STM):

使用 OSS 默认域名通过浏览器访问静态网页文件时,Response Header 中会自动加上 Content-Disposition:attachment。即从浏览器访问这些文件时,会以附件形式进行下载。

使用自定义域名通过浏览器访问静态网页文件时,在浏览器支持预览对应格式的网页文件的情况下,默认直接预览文件内容。

https://www.bilibili.com/read/cv3372025

WordPress (临时)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
version: "3.3"

services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: mysql_password
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress_password

wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- wordpress_data:/var/www/html
ports:
- "8081:80"
restart: always
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress_password
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}
wordpress_data: {}

Gitea 托管平台

其他相关项

阿里云 OSS 图床