由于众所周知的原因,国内社交平台本人是不想使用的(尤其是微博大粪坑),而之前一直使用的Twitter(现已更名为X)自从被马斯克收购之后使用体验也是每况愈下,最近又出现了向所有用户收费的动作。与其受到平台种种制约,不如干脆自己搭建一个社交平台当老大。
首先想到的自然是目前名气最大,使用人数最高的去中心化社交平台Mastodon ,但Mastodon的配置要求太高,并且会将外站内容缓存到本地,如果加入多几个中继,每天硬盘占用都要增加数个G,后续清理维护是一大麻烦,同时搭建过程也过于繁琐(官方不推荐使用docker搭建),对于只是想没事发发碎碎念的人而言无疑不是个好选择。
后来测试了Misskey 和Firefish ,搭建都很简单,不会缓存外站内容,配置要求也不高,2C4G足以胜任,其实个人更喜欢Firefish,因为Misskey不能编辑帖子,而且有3000字符的限制。但是不知道为什么Firefish使用下来不如Misskey流畅,所以最终选择了Misskey。但由于Firefish是Misskey的Fork,所以安装过程几乎一模一样。
安装 Misskey的Docker部署非常傻瓜式,参考官方文档就可以在10分钟之内搭建好。但官方的文档中没有写Meilisearch(虽然看起来像美丽的拼音,但其实Meili 是挪威神的名字,冰岛历史学家Snorri Sturluson 认为 Meili 是“遗忘之神”,因此需要一个强大的搜索引擎来找到我们可能忘记的东西)的部分,所以会造成搜索功能无法使用。这里使用的系统是Debian 12,不过由于是利用 Docker 搭建的,系统应该是无所谓的。
准备工作 安装必要软件 1 apt install -y git sudo vim
安装 Docker Engine 设置 Docker 的apt
存储库 1 2 3 4 5 6 7 8 9 10 11 12 13 sudo apt-get update sudo apt-get install ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg echo \ "deb [arch=" $(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \ " $(. /etc/os-release && echo "$VERSION_CODENAME " )" stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update
安装 Docker 软件包 1 sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
将 Misskey 克隆至本地并同步 master 1 2 3 git clone -b master https://github.com/misskey-dev/misskey.git cd misskeygit checkout master
修改配置文档 执行以下命令来复制并重命名配置文档,创建Meilisearch的环境变量文件。
1 2 3 4 cp .config/docker_example.yml .config/default.ymlcp .config/docker_example.env .config/docker.envtouch .config/meilisearch.envcp ./docker-compose.yml.example ./docker-compose.yml
需要编辑的文件有四个,分别是.config/default.yml
.config/docker.env
.config/meilisearch.env
./docker-compose.yml
下面给出需要注意的位置。
default.yml
修改为网站的网址。
1 url: https://example.tld/
修改数据库的用户名和密码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 db: host: db port: 5432 # Database name db: misskey # Auth user: example-misskey-user pass: example-misskey-pass # Whether disable Caching queries #disableCache: true # Extra Connection options #extra: # ssl: true
修改api和index,api可以通过命令openssl rand -hex 16
生成。
1 2 3 4 5 6 meilisearch: host: meilisearch port: 7700 apiKey: '' ssl: true index: 'example-tld'
docker.env
修改数据库用户名与密码。
1 2 3 4 # db settings POSTGRES_PASSWORD=example-misskey-pass POSTGRES_USER=example-misskey-user POSTGRES_DB=misskey
meilisearch.env
同样可以通过命令openssl rand -hex 16
生成,注意不能少于16字符。
docker-compose.yml
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 version: "3" services: web: build: . restart: always links: - db - redis - meilisearch depends_on: db: condition: service_healthy redis: condition: service_healthy ports: - "127.0.0.1:3000:3000" networks: - internal_network - external_network volumes: - ./files:/misskey/files - ./.config:/misskey/.config:ro redis: restart: always image: redis:7-alpine networks: - internal_network volumes: - ./redis:/data healthcheck: test: "redis-cli ping" interval: 5s retries: 20 db: restart: always image: postgres:15-alpine networks: - internal_network env_file: - .config/docker.env volumes: - ./db:/var/lib/postgresql/data healthcheck: test: "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB" interval: 5s retries: 20 meilisearch: restart: always image: getmeili/meilisearch:v1.3.4 environment: - MEILI_NO_ANALYTICS=true - MEILI_ENV=production env_file: - .config/meilisearch.env networks: - internal_network volumes: - ./meili_data:/meili_data networks: internal_network: internal: true external_network:
取消第10行和第51-62行关于meilisearch
的注释,修改第17行监听地址,防止端口暴露在公网。
编译与初始化 执行以下命令以开始编译 Misskey 并初始化数据库,这需要一些时间。
1 2 sudo docker compose build sudo docker compose run --rm web pnpm run init
启动 现在可以使用以下命令启动 Misskey。
1 sudo docker compose up -d
配置 Nginx
创建 /etc/nginx/conf.d/misskey.conf
或 /etc/nginx/sites-available/misskey.conf
并复制下面的示例配置到该文件. (文件名可以自定义,不一定强制为”misskey”)
修改示例配置中的如下内容:
将“example.tld”替换为自己的域名,请注意不只有一处.ssl_certificate
and ssl_certificate_key
应当是从 Let’s Encrypt 或自己上传的 SSL 证书的绝对路径。
若使用 CDN,例如 Cloudflare, 移除 “If it’s behind another reverse proxy or CDN, remove the following.”后面的四行(4 lines)。
如果创建了 /etc/nginx/sites-available/misskey.conf
, 那么需要创建一个为 /etc/nginx/sites-enabled/misskey.conf
的 symlink:sudo ln -s /etc/nginx/sites-available/misskey.conf /etc/nginx/sites-enabled/misskey.conf
输入 sudo nginx -t
命令来验证配置文件是否有效。
输入 sudo systemctl restart nginx
命令来重启 Nginx。
Nginx示例配置 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 # For WebSocket map $http_upgrade $connection_upgrade { default upgrade; '' close; } proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=cache1:16m max_size=1g inactive=720m use_temp_path=off; server { listen 80; listen [::]:80; server_name example.tld; # For SSL domain validation root /var/www/html; location /.well-known/acme-challenge/ { allow all; } location /.well-known/pki-validation/ { allow all; } location / { return 301 https://$server_name$request_uri; } } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.tld; ssl_session_timeout 1d; ssl_session_cache shared:ssl_session_cache:10m; ssl_session_tickets off; # To use Let's Encrypt certificate ssl_certificate /etc/letsencrypt/live/example.tld/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.tld/privkey.pem; # To use Debian/Ubuntu's self-signed certificate (For testing or before issuing a certificate) #ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem; #ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key; # SSL protocol settings ssl_protocols TLSv1.2 TLSv1.3; 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; ssl_prefer_server_ciphers off; ssl_stapling on; ssl_stapling_verify on; # Change to your upload limit client_max_body_size 80m; # Proxy to Node location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_http_version 1.1; proxy_redirect off; # If it's behind another reverse proxy or CDN, remove the following. 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 https; # For WebSocket proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; # Cache settings proxy_cache cache1; proxy_cache_lock on; proxy_cache_use_stale updating; proxy_force_ranges on; add_header X-Cache $upstream_cache_status; } }
至此,Misskey搭建完成。
注意 启用搜索 Misskey默认没有启用搜索功能,需要手动打开,将控制面板
-管理
-角色
-基本角色
-是否可以搜索帖子
修改为是
即可。
设置CDN 我们推荐使用 Cloudflare 来作为 Misskey 的 CDN。
使用 CDN 的好处
CDN 可以缓存服务器中的静态内容,减少服务器中的存储占用。
CDN 可以在大部分情况中隐藏服务器的真实 IP 地址,减少服务器被 DoS攻击的概率。
缓存内容 Misskey Web 是完全静态的,甚至不需要服务器来实时运行,所以整个 Misskey Web 可以完全存储在 CDN 中。 但是,Misskey 的 API 不能被缓存。
你需要在 CDN 服务提供商中配置如下信息
当更新 Misskey 时,不用清理缓存。
关于反代 如果使用CloudFlare作为CDN的话,其实更推荐使用cloudflared
进行反代而非Nginx。不仅因为cloudflared
实在是太简单了,只要使用过一次,后续再也不需要搜索教程(但如果使用Nginx反代,我相信没人能自己手动写一遍),而且理论上cloudflare tunnel还能降低延迟。
对象存储 推荐使用对象存储,纯净的Debian 12系统按上述步骤安装好后,硬盘占用是13G左右,因此可以将媒体文件保存到低价的对象存储中,推荐使用Backblaze ,应该是目前市面上价格最低的,如果搭配CloudFlare使用更是不需要流量费用,这里可以参考【对象存储】搭配CF带宽联盟实现流量免费 。
对象存储的配置很简单,需要注意的是可用区是https://s3.<region>.backblazeb2.com
中间的<region>
部分,不需要勾选使用代理
、上传时设置为public-read
和s3ForcePathStyle
。
结语 每个人都有社交需求,但类似Mastodon、Misskey、Firefish的去中心化分布式微博客社交网络终究是小众产品,一个没有任何经验的用户如果想要拥有自己的实例要付出巨大的时间和经济成本,最终可能还是会选择放弃自建加入其他实例或者是干脆重新回到Twitter之类的中心化社交平台。而笔者之所以写这篇文章,是希望帮助到有兴趣有意愿的人,解决其可能遇到的问题,使其能够加入到更加自由地网络中,并能够带动更多的人投身其中。
最后,希望互联网能够像最初构想的那样,自由、平等、开放、创新、共享。逃离目前的社交网络舒适圈固然有困难,但当千万人的力量集结起来,受益人终将是我们自己。
参考
Install Docker Engine on Debian
Why this project named Meili
创建您自己的Misskey实例
设置CDN
配置 Nginx