0%

因为想用docker搭建,这里主要参考了使用docker搭建Synapse[Matrix],关于域名问题参考了Matrix踩坑记(一)和南狐的手把手debug。

域名

参考Matrix踩坑记(一),matrix是可以和其他服务共用一个域名的。因为我后续希望账号都是和社畜站的id完全相同,所以我使用retirenow.top这个域名,与此同时服务挂在cafe.retirenow.top。没有这个问题的,都用一样的域名就行。

搭建Synapse

按照教程建立/data/synapse/下的三个文件夹:

1
2
3
4
mkdir /data/synapse
mkdir /data/synapse/data
mkdir /data/synapse/postgres
mkdir /data/synapse/redis

之后都直接按照教程一步步执行即可,输入\q退出。
搭建时使用的所有域名均为retirenow.top。

如果使用不同域名,在修改/data/synapse/data/homeserver.yaml时,除了教程里的内容,还需要修改:

1
public_baseurl: https://cafe.retirenow.top

如果你之后使用cloudflare反代,由于关闭了8448端口,所以这边也要改:

1
serve_server_wellknown: true

到这一步,打开 http://127.0.0.1:55800/ 应该会显示matrix的server界面,提示:

Your Synapse server is listening on this port and is ready for messages.

这就是成功了!就是这么简单!

配置Riot web界面

服务器配置好以后来配置客户端,这边推荐全平台的element。需要注意的是,这里用的是cafe.retirenow.top这个域名,也就是通过打开:

https://cafe.retirenow.top/

来使用matrix。所以cloudflare里应该添加的是cafe到服务器的DNS映射,nginx也应该监听cafe.retirenow.top,只有在element的设置文件中需要指定server_name为retirenow.top。

这里解压到任何路径都可以,因为和前面的server是独立的。我的话解压到了/data/synapse/并改名为element-web:

1
2
3
4
5
6
wget https://github.com/vector-im/element-web/releases/download/v1.10.9-rc.3/element-v1.10.9-rc.3.tar.gz
tar -zxvf element-v1.10.9-rc.3.tar.gz -C /data/synapse
mv /data/synapse/element-v1.10.9-rc.3 /data/synapse/element-web
cd /data/synapse/element-web
cp config.sample.json config.json
vim /data/synapse/element-web/config.json

上面的下载地址请自行替换为最新版本地址

在”m.homeserver”中,修改”base_url”和”server_name”分别如下:

1
2
3
4
5
6
7
8
9
"default_server_config": {
"m.homeserver": {
"base_url": "https://cafe.retirenow.top",
"server_name": "retirenow.top"
},
"m.identity_server": {
"base_url": "https://vector.im"
}
},

配置nginx

在之前就配好的retirenow.top的nginx配置中加上:

1
2
3
4
5
6
7
8
9
10
11
# Matrix
location /.well-known/matrix/client {
return 200 '{"m.homeserver": {"base_url": "https://cafe.retirenow.top"}}';
default_type application/json;
add_header Access-Control-Allow-Origin *;
}
location /.well-known/matrix/server {
return 200 '{"m.server": "cafe.retirenow.top:443"}';
default_type application/json;
add_header Access-Control-Allow-Origin *;
}

然后新建一个cafe.retirenow.top的配置。

1
2
cd /etc/nginx/sites-available
vim cafe.retirenow.top.conf

依然按照使用docker搭建Synapse[Matrix]配置,但是删掉上面被挪到retirenow.top的那几行。
更改所有域名为cafe.retirenow.top,然后更改cafe.retirenow.top.conf的这三行为:

1
2
3
ssl_certificate /etc/letsencrypt/live/cafe.retirenow.top/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/cafe.retirenow.top/privkey.pem; # managed by Certbot
root /data/synapse/element-web;

申请证书,reload nginx:

1
2
3
certbot certonly --nginx -d cafe.retirenow.top
ln -s /etc/nginx/sites-available/cafe.retirenow.top.conf /etc/nginx/sites-enabled/
systemctl reload nginx

我的certbot一定要这么搞才可以成功,至今不知道为什么,会搞certbot的用你自己的流程搞就可以了。要点就是这里要用cafe.retirenow.top.conf。

cloudflare添加好DNS记录,就可以直接打开啦:

https://cafe.retirenow.top/

配置管理页面

新建一个管理员账号:

1
2
cd /data/synapse
docker-compose exec synapse register_new_matrix_user -c /data/homeserver.yaml http://localhost:8008

按照提示输入账号密码,在Make admin [no]: 时输入yes,之后可以直接在网页上改密码且不需要邮箱,很方便,所以不用配邮箱服务了。

然后搭建管理界面:

1
docker run -d -p 8100:80 awesometechnologies/synapse-admin

就可以通过访问:
http://localhost:59242
来使用管理页面。

2022-4-21 Update:

给大家提供了更方便的方法,现在可以直接使用这个链接给你的代码提pr,v3.5.1可以无痕merge。登陆你的账号并把base repository改为你的提交即可。

前言

本文会尽我可能解释涉及到的所有概念,但还是推荐有一定的 git 使用基础后阅读。推荐阅读的前置内容:《如何利用Docker搭建Mastodon实例(二):进阶魔改篇》 的升级章节。

最初是有一位大神写了 local-only 的功能,可以让嘟文限制在本实例而不流出外部。此 pr 并没有被官方采纳,但是一些站点都有增加这个魔改功能。

本篇以我的 local-only commit需要改个bug )为例,说明如何合并这种代码量较大的魔改(代码量小的通常找到位置复制粘贴即可,参考文章开头的教程 )。

从远程仓库拉取代码

首先将你的代码仓库 git clone 到本地,或直接 cd 到已有的仓库目录:

1
2
$ git clone https://github.com/yourname/mastodon.git 
$ cd mastodon

此时如果查看远程连接情况,只会看到一个名为 origin 的远程仓库链接,也就是你自己的远程仓库的名字。

1
2
3
$ git remote -v
origin https://github.com/yourname/mastodon.git (fetch)
origin https://github.com/yourname/mastodon.git (push)

此时如果查看分支情况,一般而言默认是只 clonemain 分支(即 origin/main)。

1
2
$ git branch -vv
* main 4bdce2c51 [origin/main] 你最新的 commit 内容 (#17618)

(可选)创建一个专门用于处理此次合并的分支

如果你熟悉 git 的分支管理,此时可以新建一个专门的分支,最后再并入主干,本文采取直接合入主干的方式,故这部分不展开讲。

设置远程仓库连接

一个基础的 git 概念是,在本地的这个是你的本地代码仓库,而 GitHub 只是代码的远程托管,本地和远程仓库可以理解为一个仓库的两个副本,你可以把你的代码发送给远程仓库,也可以从远程仓库拉取,而且一个本地仓库可以连接不止一个远程仓库。

现在添加我的 local-only 的仓库 作为 upstream

1
$ git remote add upstream https://github.com/retirenow/mastodon.git

此时再查看远程连接:

1
2
3
4
5
$ git remote -v
origin https://github.com/yourname/mastodon.git (fetch)
origin https://github.com/yourname/mastodon.git (push)
upstream https://github.com/retirenow/mastodon.git (fetch)
upstream https://github.com/retirenow/mastodon.git (push)

就会有两个远程,名字分别为 originupstream

拉取分支并合并代码

设置好远程以后,我们就可以从 upstream 拉取含有 local-only 的分支:

1
$ git fetch upstream main:instance_only_statuses

这边因为分支都叫 main,为了区分我给从 upstream 拉取的本地分支重命名了一下。上面这句话的意思是,从 upstream 拉取它的 main 分支,并命名为本地的 instance_only_statuses

这时候查看分支情况,会有两个分支:

1
2
3
$ git branch -vv
instance_only_statuses d8c03d962 retirenow 最新的 commit 内容
* main 4bdce2c51 [origin/main] 你最新的 commit 内容 (#17618)

星号代表你现在处于 main 分支上。

现在 cherry-pick 这个 commit:

1
$ git cherry-pick 6a2ca72f711849586f49c44dde555abb0ad13179

那一长串编码是这个 commit 的哈希值,可以唯一指定找到这串 commit ,可以在 commit 页面找到。

cherry-pick 用于只合并特定 commit ,和 merge 类似,merge 是合并两个分支(包含所有 commit)。

处理冲突

cherry-pick 之后,如此大的改动量通常会提示代码有冲突,推荐用 vscode 处理。

从侧边的 git 点进去看:

其中暂存的更改(Staged Changes)就是已经被自动合并好的代码,不需要处理,而合并更改(Merge Changes)则是需要处理的冲突文件,具体数量因人而异。

点开合并更改中一个文件,在冲突的地方,会有如下所示:

Accept Current Change 是保持现在(main分支)的代码,Accept Incomming Change 是用 local-only 的代码,Accept Both Changes 则是保留两者。

这里的处理其实需要一点灵性和连蒙带猜,可以结合原始pr的file change理解一下它增加代码的逻辑然后去选择如何更改。以上图为例,显然是因为我们main分支增加了一个叫 “ordered_media_attachment_ids” 的东西,而 local only 也增加了 “local_only”,所以我们的选择就是 Accept Both Changes。

处理完冲突后

一般而言,如果你是参考这个教程进行代码魔改,此时你只需要提交你的改动:

1
2
3
$ git add .
$ git commit -m "local-only"
$ git push -u origin main

然后静待 GitHub 编译好镜像,你再拉取使用即可。

我在这一步遇到了报错500,参考这篇文章对数据库进行 migrate 再重启即可。

在 docker 容器中 debug

但是通常来说如此大的代码改动量,有一定风险不能一次性跑通,如果直接使用镜像遇到问题,我推荐参考《Docker 部署的 mastodon 在容器内 debug》。或者如果不放心也可以先在容器内部编译通过再拉取镜像。

首先进入 docker 容器:

1
$ docker exec --user root -it mastodon_web_1 /bin/bash

容器里默认是没有 git 的,需要先安装 git

1
2
$ apt-get update
$ apt-get install git

这时候可能会遇到报错

1
E: Archives directory /var/cache/apt/archives/partial is missing

解决方案:

1
$ mkdir -p /var/cache/apt/archive/partial

继续:

1
$ apt-get install git

即可正确安装。

进入到我们的代码目录:

1
2
$ cd /mastodon
$ git init

然后添加你的远程仓库并拉取最新的代码:

1
2
3
$ git remote add origin https://github.com/yourname/mastodon.git
$ git fetch origin main:main
$ git checkout -f main

也可以一开始就直接在 docker 容器里合代码,如果你会用 vscode 连接 docker 容器,原理都是一样的。

接下来 precompile:

1
$ RAILS_ENV=production bundle exec rails assets:precompile

通过后退出并 docker-compose restart,就可以直接在网页上预览效果了。

之前写过一个vscode安利帖,最近因为重新配置环境,顺便把更基础的部分补充一下。

安装必要软件

Anaconda3

官网下载,安装时勾选add anaconda3 to my PATH enviroment variable

VScode

官网下载,安装时勾选添加到PATH,重启使其生效。

git

官网下载,并配置好个人信息:

1
2
git config --global user.email "[email protected]"
git config --global user.name "Your Name"

docker

官网下载。

下载重启后,打开docker,通常会报错:WSL 2 installation is incomplete,并给出一个下载链接,点进去以后下载一个msi然后安装即可。

配置 VScode

重启电脑,打开 vscode,下载 python 插件,有需要可以改成中文,参考vscode安利帖

在 vscode 的菜单中选择:Terminal-new terminal

在出现的终端界面右边选择默认terminal为cmd(重要):


再点+出现新的cmd命令窗口,输入

1
Conda activate base

激活conda,如果最左边有个(base)说明成功了。

另外我的 vscode 出现画面很糊的诡异情况,这时候去快捷方式的目录,右键快捷方式,选择属性,在目标中增加一个 --disable-gpu 参数,如:

1
"C:\Program Files (x86)\Microsoft VS Code\Code.exe" --disable-gpu

配置清华镜像

如果 conda 和 pip 太慢,可以配置清华镜像:

1
2
3
4
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --setshow_channel_urls yes
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pip -U
Pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

TL; DR:

进入container改代码:

1
docker exec -it mastodon_web_1 /bin/bash 

预编译确保不报错:

1
RAILS_ENV=production bundle exec rails assets:precompile

退出并重启容器:

1
docker-compose restart

感谢小柠檬 @lemon@nya.lemonade.moe 用自己的实例测试研究出这套可行方案!

非docker的魔改方法

可参考这篇文章:进阶魔改:修改字数上限、媒体上限、投票上限、添加自定义主题、界面用语、非登陆用户有限显示,附阻止本站嘟文流入某站点方法

一般的修改逻辑是:

  • 修改对应代码
  • 预编译
1
RAILS_ENV=production bundle exec rails assets:precompile
  • 重启服务
1
2
3
systemctl restart mastodon-sidekiq
systemctl reload mastodon-web
systemctl restart mastodon-streaming

docker 魔改方法

参考这篇文章:如何利用Docker搭建Mastodon实例(二):进阶魔改篇

在其中的“如何在Docker上保留你的魔改”部分,提到了三种方法:

  1. 进入容器修改;
  2. docker-compose build本地编译;
  3. 利用GitHub编译镜像,直接拉取最新镜像后重启。

对于较为简单的改动,第三种方法已经够用,但有时候我们需要对改动进行调试,以确保网站按照我们预想的效果运行,此时如果每次改动代码都要走提交-编译镜像-拉取镜像-重启的流程,调试起来就会非常不方便。本文就提供了第一种方法的补充,进入容器修改代码并实时生效。

建议的workflow是:

  • 进入容器修改代码并确保调试完成
  • 在容器外修改代码并走传镜像的流程进行正式更新

在容器内debug

先进入容器,如果是按照官方的docker-compose.yml,容器名应该是mastodon_web_1,可用docker ps确认:

1
docker exec -it mastodon_web_1 /bin/bash 

进入container改代码,然后预编译:

1
RAILS_ENV=production bundle exec rails assets:precompile

这步不报错之后exit退出,然后:

1
docker-compose restart

即可在站点实时看到效果。

本方法适合进入docker进行一些调试并且可以快速在网页端看到修改结果,确认无误后还是推荐打包成镜像再docker-compose down/up -d,参考下文。

利用GitHub编译镜像

参考这篇文章:如何利用Docker搭建Mastodon实例(二):进阶魔改篇

如果有500之类的报错可以参考:数据库适应

对数据进行migrate,之后需要再重新docker-compose down/up -d一次,即:

1
2
3
docker-compose run --rm web rails db:migrate
docker-compose down
docker-compose up -d

Crontab是一个运行定时脚本的工具,我在这里翻车了n次,记录一下debug过程。

常用命令

1
2
3
4
service cron status # 查看运行状态和报错信息
service cron reload # 重新载入
service cron restart # 重启
vim /etc/crontab #编辑 crontab

Debug

Missing newline before EOF

报错内容:

1
(*system*) ERROR (Missing newline before EOF, this crontab file will be ignored)

解决方案

Correct this error simply by adding a blank line at the end of your crontab.

就是在crontab文件的末尾添加一个新的空行(回车),就离谱……

session opened for user root by (uid=0)

报错内容:

1
pam_unix(cron:session): session opened for user root by (uid=0)

解决方案

打开文件:

1
vim /etc/pam.d/common-session-noninteractive

找到这一行:

1
session required pam_unix.so

并在其上方添加:

1
session [success=1 default=ignore] pam_succeed_if.so service in cron quiet use_uid

然后重启:

1
service cron restart

在网上看到别人家的博客有GitHub登陆评论的功能,立刻表示:“我也要!”

一开始使用的是next自带的gitalk设置,然而在我的一番努力下依然没有配好,于是换成了Giscus,参考Giscus的优点

Giscus的配置非常简单!按照上文的顺序配好了以后,卡在最后一步“嵌入到博客文章模板底部”,于是搜到了这个插件,安装:

1
$ npm install hexo-next-giscus --save

然后在 hexo 的 _config.yml 添加:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
giscus:
enable: false
repo: # Github repository name
repo_id: # Github repository id
category: # Github discussion category
category_id: # Github discussion category id
# Available values: pathname | url | title | og:title
mapping: pathname
# Available values: 0 | 1
reactions_enabled: 1
# Available values: 0 | 1
emit_metadata: 1
# Available values: light | dark | dark_high_contrast | transparent_dark | preferred-color-scheme
theme: light
# Available values: en | zh-C
lang: en
# Available value: anonymous
crossorigin: anonymous

enable: false改为true,并参考Giscus生成的脚本的元素依次填入设置。

一开始是在_config.next.yml不起作用,不知为何。

最后:

1
2
3
hexo clean
hexo generate
hexo deploy

刷新页面后就可以看到评论页面啦!

快来给我评论吧~~

写在前面:
本文备份方法我还在验证中,请谨慎使用,最好以防万一多导出一份backup.dump

Why:为什么要备份

定期备份是好习惯,自从体验过一次wordpress搬家以后深刻感受到,有(异地)备份走遍天下都不怕。因为各种教备份的资料都比较全,本文主要是个人记录+学习用,如果想深入了解备份究竟在做什么也可以参考这篇文章。

当你有一份长毛象的异地备份,你可以:

  • 迁移站点到其他服务器
  • 在服务器完全瘫痪时或不小心重装后,依然可以还原所有数据库内容

What:备份哪些内容

俗话说得好,没有经过检验的备份不是好备份。那么最快让我们清楚需要备份什么的方式就是看还原/迁移站点需要什么。

这里参考了非docker站点迁移到dockerdocker迁移到docker 两篇资料,大致上分为三步:

1. 转移配置文件

配置文件也就是你的mastodon安装目录(按照pullopen的教程的话应该是/home/mastodon/mastodon)下的:

1
2
.env.production 
docker-compose.yml

也就是在更改站点设置中最常用的两个文件。

2. 转移数据库

这里有两个方法:

  • 通过备份文件backup.dump 进行转移,也就是备份的最关键内容,通常通过pg_dump导出备份,再通过pg_restore进行还原。

  • 如果是docker,可以直接复制./postgres/./redis/,并对./postgres/赋权,参考将站点从Docker迁移至Docker

3. 转移媒体文件

这里分为两种情况,如果你已经配置了媒体文件在云存储,这一步是不需要的。如果你没有配置过,那么你的所有文件都在./public/system/目录下。具体而言有:

1
2
3
4
5
6
7
$ cd /home/mastodon/mastodon/public/system
$ du -h --max-depth=1
9.6M ./media_attachments
3.3G ./cache
20M ./custom_emojis
13M ./accounts
3.4G .

其中./cache是外站存储,其他都是本站的数据。我们当然希望除了外站存储以外,对本站的所有数据都做好备份。

关于定期清除外站存储,请参考这个嘟文,我的crontab设置:

1
2
3
30 4    * * *   root    docker exec mastodon_web_1 tootctl media remove --days=14 >> /home/mastodon/log/mastodon/all.log 2>&1
30 4 * * * root docker exec mastodon_web_1 tootctl media remove-orphans >> /home/mastodon/log/mastodon/all.log 2>&1
30 4 * * * root docker exec mastodon_web_1 tootctl statuses remove --days=180 >> /home/mastodon/log/mastodon/all.log 2>&1

我是直接启动容器执行tootctl命令,更多相关内容可以通过使用脚本的tootctl或者非docker安装的tootctl了解。

总结:如果是docker的话,直接对除./public/system/cache以外整个文件夹和个别配置文件进行备份即可。

Where:备份放在哪里

本地备份

本文将备份文件和备份脚本都放在/opt/mastodon-backup 下,你也可以选择任何你喜欢的安全位置。

异地备份

最好的备份一定是异地备份。pullopeno3o 都推荐了Scaleway云备份,并附上了详细的资料。

When:什么时候备份

建议设置每天晚上自动备份一次,可以使用crontab创建定时任务。

Who:谁来备份

当然是站长啊还有谁!

How:如何备份

啰嗦了这么久终于到了这一步,我只是希望在我真正操作之前能够明白我在做什么。

这一节脚本主要参考利用Scaleway备份数据库

本地备份

只看脚本的前半部分:

1
2
3
4
5
6
7
8
9
#!/bin/bash
source /etc/profile
now=$(date "+%Y%m%d-%H%M%S")
origin="/home/mastodon/mastodon"
target="scaleway:你的bucket名字"
echo `date +"%Y-%m-%d %H:%M:%S"` " now starting export"
/usr/bin/docker exec pg容器名 pg_dump -U postgres -Fc mastodon_production > ${origin}/backup.dump &&
echo `date +"%Y-%m-%d %H:%M:%S"` " succeed and upload to s3 now"
/usr/bin/zip -P 密码 ${origin}/backup_${now}.zip ${origin}/backup.dump

前面定义了一些路径和时间等,先通过pg_dump导出backup.dump,再将其加密压缩为backup_${now}.zip,但从上文可见,对于docker安装的情况,直接copy文件夹即可,所以我对这部分做了一些改动并参考o3o的配置备份脚本,增加了一些关键信息的备份,我的完整本地备份脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash

# Save this file at /opt/mastodon-backup/backup_local.sh
# Set a cronjob: 0 5 * * * root /bin/bash /opt/mastodon-backup/backup_local.sh >> /opt/mastodon-backup/logs/backup_local.log 2>&1

# Set backup_folder and name
now=$(date "+%Y%m%d-%H%M%S")
origin_folder="/home/mastodon/mastodon"
backup_folder="/opt/mastodon-backup/dbbackup"

# Clean up old backup file
rm -r ${backup_folder}/*

# Generating a mastodon backup exclude cache
echo `date +"%Y-%m-%d %H:%M:%S"` " now starting export"
/usr/bin/zip -P 密码 -rqx=${origin_folder}/public/system/cache/* ${backup_folder}/backup_${now}.zip ${origin_folder}

# Copying important files
cp -r /etc/nginx/sites-available ${backup_folder}
echo `date +"%Y-%m-%d %H:%M:%S"` " done!"

可以单独运行一次脚本看看是否正确备份,运行后查看备份目录:

1
2
3
4
$ ls /opt/mastodon-backup/dbbackup/ -lh
total 76M
-rw-r--r-- 1 root root 76M Feb 20 00:09 backup_20220220-000931.zip
drwxr-xr-x 2 root root 4.0K Feb 20 00:09 sites-available

我将这个脚本存为backup_local.sh,在我配置好Scaleway之前守护我的数据,将其放在crontab下定期运行:

1
0 5 * * * root /bin/bash /opt/mastodon-backup/backup_local.sh.sh >> /opt/mastodon-backup/logs/backup_local.sh.log 2>&1

备份时间设在清除外部缓存半小时后。

异地备份

再看原脚本的后半部分

1
2
3
4
/usr/bin/rclone copy ${origin}/backup_${now}.zip ${target} &&
echo `date +"%Y-%m-%d %H:%M:%S"` " ok all done"
rm -f ${origin}/backup.dump ${origin}/backup_${now}.zip
/usr/bin/rclone --min-age 7d delete ${target}

rclone copy是将压缩后的备份文件按照配置好的设置上传至Scaleway,之后rm -f删除本地的备份文件,最后设置rclone删除大于7天的备份文件。这一步也可以直接在Scaleway删除,参考循环销毁备份文件

在我更改后的脚本,我采取的方法是每次先删除上一次的备份文件,而不是在上传后删除,这样可以在本地和Scaleway都有一个备份。

Scaleway和rclone的设置可参考利用Scaleway备份数据库设置定期异地备份长毛象数据库和关键配置

注意,备份的bucket要和媒体存储的分开,并且设为private!!

可以用

1
rclone ls scaleway:你的bucket名称

查看bucket里的文件,确认是否正常上传和删除。

最终我的完整脚本:

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
#!/bin/bash

# Save this file at /opt/mastodon-backup/backup.sh
# Set a cronjob: 0 5 * * * root /bin/bash /opt/mastodon-backup/backup.sh >> /opt/mastodon-backup/logs/backup.log 2>&1

# Loading /etc/profile
source /etc/profile

# Set backup_folder and name
now=$(date "+%Y%m%d-%H%M%S")
origin_folder="/home/mastodon/mastodon"
backup_folder="/opt/mastodon-backup/dbbackup"
target_bucket="scaleway:你的bucket名称"

# Clean up old backup file
rm -r ${backup_folder}/*

# Generating a mastodon backup exclude cache
echo `date +"%Y-%m-%d %H:%M:%S"` " now starting export"
/usr/bin/zip -P 密码 -rqx=${origin_folder}/public/system/cache/* ${backup_folder}/backup_${now}.zip ${origin_folder}

# Copying important files
cp -r /etc/nginx/sites-available/ ${backup_folder}
echo `date +"%Y-%m-%d %H:%M:%S"` " local backup done!"

# upload to scaleway
/usr/bin/rclone copy ${backup_folder}/ ${target_bucket}
echo `date +"%Y-%m-%d %H:%M:%S"` " ok all done"

# delete backup longer than 7d
/usr/bin/rclone --min-age 7d delete ${target_bucket}

单独运行一遍可以成功后,就可以把crontab中的backup_local.sh改为backup.sh啦!这样你就有了一个:

  • 本地和scaleway双重备份
  • 本地保留一天,scaleway保留7天
  • 包含nginx设置和整个mastodon目录

的备份啦!

Prerequisites

参考蓝盒子站长的教程 ,一直进行到把 docker 和 docker-compose 装好。

Checklist:

  • ssh-key设置并关闭密码登录
  • 开启防火墙
  • 域名映射到服务器ip
  • 安装成功 docker 和 docker-compose

Postgres database

Update 2022.2.19:

这一步我已经找到原因了,是因为在原教程中,写的是:

刚才docker-compose.yml文件中,数据库(db)部分的地址为./postgres:/var/lib/postgresql/data,因此你的数据库绝对地址为/home/mastodon/mastodon/postgres。

然后我发现我wget最新的docker-compose配置,这边已经变成了:

1
2
volumes:
- ./postgres14:/var/lib/postgresql/data

所以我当时按照教程运行:

1
docker run --name postgres12 -v /home/mastodon/mastodon/postgres:/var/lib/postgresql/data -e   POSTGRES_PASSWORD=设置数据库管理员密码 --rm -d postgres:12.5-alpine

实际上是在./postgres里操作,但我应该在./postgres14里操作才能真的把数据写进docker。所以这里应该把命令改为:

1
docker run --name postgres12 -v /home/mastodon/mastodon/postgres14:/var/lib/postgresql/data -e   POSTGRES_PASSWORD=设置数据库管理员密码 --rm -d postgres:12.5-alpine

或者把docker-compose中的

1
2
volumes:
- ./postgres14:/var/lib/postgresql/data

改回

1
2
volumes:
- ./postgres:/var/lib/postgresql/data

总之目的都是让我们能真的实际操作到postgres的数据并让docker能访问到。

这里因为我还是按照之前的路径操作,后来直接进入mastodon_db_1才真正写到了./postgres14里,所以我的./postgres实际上是没有用的,我就把整个文件夹删掉了。

原文:

在设置mastodon的时候,运行:

1
sudo docker-compose run --rm web bundle exec rake mastodon:setup

我在这个地方卡住了非常久,在postgres那里尝试了各种版本教程的排列组合最后的结果都是:

1
2
Database connection could not be established with this configuration, try again.
FATAL: role "mastodon" does not exist

后来我认真看了一下这一步,它的输出是:

1
2
Starting mastodon_db_1    ... done
Starting mastodon_redis_1 ... done

查看docker container也是这两个docker在跑:

1
2
3
4
$ docker container list -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bd7debf13a49 redis:6-alpine "docker-entrypoint.s…" 31 minutes ago Up 31 minutes (healthy) mastodon_redis_1
30c6e3b74c40 postgres:12.5-alpine "docker-entrypoint.s…" 31 minutes ago Up 31 minutes (healthy) mastodon_db_1

于是我尝试把教程中4. 初始化PostgreSQL的这句话:

1
docker exec -it postgres12 psql -U postgres

改成

1
docker exec -it mastodon_db_1 psql -U postgres

之后再添加mastodon用户:

1
2
> CREATE USER mastodon WITH PASSWORD 'your_password' CREATEDB;
> exit

完整操作看起来是这样的:

1
2
3
4
5
6
7
$ sudo docker exec -it mastodon_db_1 psql -U postgres
psql (12.5)
Type "help" for help.

postgres=# CREATE USER mastodon WITH PASSWORD 'your_password' CREATEDB;
CREATE ROLE
postgres=# exit

这时候再运行:

1
sudo docker-compose run --rm web bundle exec rake mastodon:setup

按照下列输出就可以通过验证了:

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
Domain name: example.com

Single user mode disables registrations and redirects the landing page to your public profile.
Do you want to enable single user mode? No

Are you using Docker to run Mastodon? Yes

PostgreSQL host: mastodon_db_1
PostgreSQL port: 5432
Name of PostgreSQL database: mastodon
Name of PostgreSQL user: mastodon
Password of PostgreSQL user: (这里写上面你给mastodon设置的your_passwords)
Database configuration works! 🎆

Redis host: mastodon_redis_1
Redis port: 6379
Redis password: (这里是直接回车,没有密码)
Redis configuration works! 🎆

Do you want to store uploaded files on the cloud? No

Do you want to send e-mails from localhost? No
SMTP server: smtp.zoho.eu
SMTP port: 587
SMTP username: 你的zoho管理员邮箱地址
SMTP password: 你的zoho管理员密码
SMTP authentication: plain
SMTP OpenSSL verify mode: none
E-mail address to send e-mails "from": 你的zoho管理员邮箱地址
Send a test e-mail with this configuration right now? no

This configuration will be written to .env.production
Save configuration? Yes
Below is your configuration, save it to an .env.production file outside Docker:

把接下来的部分一直到

1
It is also saved within this container so you can proceed with this wizard.

两行绿字中间的所有内容都复制下来。

接下来依然按照蓝盒子教程走,两个问题选yes,输入管理员账号。

配置nginx

这边又出了问题,按照教程走下来在这一步报错:

1
2
3
$ sudo systemctl reload nginx
Job for nginx.service failed.
See "systemctl status nginx.service" and "journalctl -xe" for details.

查看报错信息:

1
2
3
$ sudo nginx -t
nginx: [emerg] no "ssl_certificate" is defined for the "listen ... ssl" directive in /etc/nginx/sites-enabled/example.com.conf:25
nginx: configuration file /etc/nginx/nginx.conf test failed

原来是证书没有设置好。这边我把soft link先取消了(否则会报错),运行

1
2
3
sudo rm /etc/nginx/sites-enabled/example.com.conf
sudo certbot certonly --nginx -d example.com
sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/

(这边一定要加 certonly 这个参数!我因为这一步debug了一整天)

然后把example.com.conf 里这两行取消注释(#删掉)

1
2
3
# Uncomment these lines once you acquire a certificate:
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

记得上面的example.com实际上应该是你的域名。

要确保你的nginx -t没有任何问题,我遇到了warning结果最后真的是那个warning导致的错误,不要忽略warning!

最后可以通过

1
certbot renew --dry-run

测试证书的自动更新是否起效,--dry_run就是仅打印信息,不实际执行。

这一步很多教程会教你设置定期任务来更新,但实际上certbot是会自动更新的(参考这篇文章 )。

参考资料:

https://pullopen.github.io/%E5%9F%BA%E7%A1%80%E6%90%AD%E5%BB%BA/2020/10/19/Mastodon-on-Docker.html

https://gist.github.com/TrillCyborg/84939cd4013ace9960031b803a0590c4

https://peterbabic.dev/blog/running-mastodon-with-docker-compose/

https://www.howtoforge.com/how-to-install-mastodon-social-network-with-docker-on-ubuntu-1804/

https://www.alibabacloud.com/blog/how-to-install-mastodon-using-docker-on-alibaba-cloud-ecs_595049

https://www.linode.com/docs/guides/install-mastodon-on-ubuntu-2004/

https://www.notion.so/Mastodon-042a05ee29a048df8b2c1afd49e4c49b

参考教程: https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-with-docker-compose

Step 1 设置反代

这一步主要是对nginx进行设置。

反代是什么?为什么要反代?一般而言例如VPN这样的服务就是正向代理,代理客户端访问各个网站。而反向代理是服务器的代理。

listen:告诉nginx要监听哪个端口。这步暂时只用了80端口,也就是HTTP用的。之后SSL下来了以后加上443,也就是HTTPS用的。

server_name:域名,这里似乎其实只需要写blog.konata.co就够了?前后只是优先级?

index:网页的index文件,按照优先级排序

root:这个是根目录地址,之后会在dockerfile里mount到这个目录下。

Step 2 设置环境变量

这一步主要是把密码用户名加到环境变量里,然后由于涉及敏感信息,所以额外添加了.gitignore和.dockerignore

Step 3 设置docker-compose

Docker-compose和dockerfile是两个东西,各自用处见:

https://www.runoob.com/docker/docker-dockerfile.html

https://www.runoob.com/docker/docker-compose.html

Docker-compose是用来配置容器内服务的。这里依次配置了db(数据库),wordpress,webserver(nginx反代)和certbot(https证书)。

在services中,每个服务器的image指定了是从哪个镜像启动服务。这里用的都是公开的现成的镜像,所以可以直接启动。

这一步wordpress用的镜像是image: wordpress:5.1.1-fpm-alpine,版本比较旧,可以替换成这里 更新的tag,如5.9.0-fpm-alpine,也许就可以解决php版本过老的问题(待确认)。

Step 4 获取SSL证书

要用https而不是http,需要获取SSL证书。在上一步已经配置好了certbot,这一步首先启动docker-compose。

docker-compose up 是启动,加上-d是在后台运行。

docker-compose ps 可以检查服务运行情况。

docker-compose exec webserver ls -la /etc/letsencrypt/live 这句话指的是启动webserver的docker然后查看域名是否设置成功。从名字上看似乎用的是Let’s Encrypt的服务。如果设置成功,就可以进入docker-compose.yml--staging这个调试用的参数改成--force-renewal,重新申请一个正式的证书。

docker-compose up --force-recreate --no-deps certbot 使最新的docker-compose.yml生效。

Step 5 修改nginx

因为已经申请到了SSL证书,现在要返回修改nginx

先把webserver服务停了,然后下载certbotnginx配置文件options-ssl-nginx.conf,删除旧的nginx.conf改成新的nginx.conf,再修改docker-compose.ymlwebserver的配置,把443端口添加上去。

docker-compose up --force-recreate --no-deps webserver 使最新的docker-compose.yml生效。

Step 6 前端安装

到这步为止,nginx反代,SSL证书,wordpress,全部都安装好并且在后台运行了。这时候访问域名,就会出现wordpress的安装界面。全程网页操作,简单易懂。

Step 7 定期更新证书

因为证书90天内有效,所以要写一个脚本每隔一段时间(小于90天)就重新申请一次证书。脚本内容大概是renew certbot并删除多余镜像,之后把脚本的权限设为可执行。调用crontab来定期运行脚本。

*/5 * * * *是每五分钟运行一次,为了快速出测试结果。

\>> /var/log/cron.log 2>&1是把输出写到log文件里,方便查看。

确认没有问题以后,改为0 12 * * *,是每12小时更新一次,需要更新得这么频繁吗?

同时把调试用的参数--dry-run从脚本里删掉。

操作系统为 CentOS Linux release 7.2,试过网上的一些方法例如软链接,增加graph路径都没有用,自己摸索找到了配置路径的位置,记录一下。

  1. 使用df -h 查看磁盘状况:
1
2
3
4
5
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 99G 91G 3.4G 97% /
/dev/vdb1 493G 62G 406G 14% /data
overlay 99G 91G 3.4G 97% /var/lib/docker/overlay2/xxx

可以看到/var/lib/docker/放满了,可以移到data目录下。

同时可以先确认一下目前的 docker 目录:

1
2
3
4
$ docker info
...
Docker Root Dir: /var/lib/docker
...
  1. 清理无用的内容
1
$ docker system prune

可添加-a清除得更彻底。之后查看磁盘状况:

1
2
3
4
5
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 99G 83G 12G 88% /
/dev/vdb1 493G 62G 406G 14% /data
overlay 99G 83G 12G 88% /var/lib/docker/overlay2/xxx

有所缓解,但12G依然不够用,需要更改 docker 目录到 /data下。

  1. 停止docker服务
1
$ systemctl stop docker
  1. 创建新的docker工作目录
1
$ mkdir -p /data/dockerlib
  1. 迁移/var/lib/docker
1
rsync -avz /var/lib/docker /data/dockerlib
  1. 改动配置文件
1
$ vim /etc/docker/daemon.json

在文件中更改

1
"data-root": "/data/dockerlib/docker",
  1. 重启docker服务
1
2
3
4
5
systemctl daemon-reload

systemctl restart docker

systemctl enable docker
  1. 确认是否配置成功
1
2
3
4
$ docker info
...
Docker Root Dir: /data/dockerlib/docker
...
  1. 确认 docker 已经成功转移

修改原 docker 路径名,再进行一些操作

1
2
3
$ mv /var/lib/docker /var/lib/docker_temp
$ docker image list
$ docker container list

在这一步我发现之前的 container 进去会有问题,但是重启后可以重新进入:

1
2
3
$ docker stop xxx
$ docker start xxx
$ docker exec -it xxx /bin/bash

确认无误后可以删除,为了防止出错可以用一阵子再删

1
$ rm -rf /var/lib/docker_temp