简介
只部署服务,不讲原理。
本机配置:MacBook Pro M2 Max 32 GB
Mastodon 介绍
Mastodon 是一个自由、开源的去中心化的微博客平台,类似于 Twitter,但是使用分布式的架构,用户可以在不同的实例(服务器)之间自由迁移,并且可以互相关注和互相交流。Mastodon 的用户可以发布短文本、图片、视频、音频等内容,并且可以使用标签来组织和浏览内容。
Mastodon 的用户界面简洁、易用,支持自定义主题和语言,同时也支持多种客户端应用程序,包括 Web、Android、iOS 等。Mastodon 的消息是加密的,用户可以选择公开或私密地发布消息,同时也可以选择将消息限制在特定的用户或实例之间。
Mastodon 的去中心化架构使得其具有较高的安全性和可靠性,不易受到单点故障和攻击。同时,Mastodon 的开源性质也使得其具有较高的灵活性和可扩展性,开发者可以根据自己的需求进行定制和扩展。
总之,Mastodon 是一个自由、开源、去中心化的微博客平台,为用户提供了更加安全、可靠、灵活的社交体验。
(介绍来自ChatGPT3.5)
部署实践
搜索Mastodon你会发现有很多容器化部署的文章,可以参考借鉴。从完全部署运行后给我的感觉,只要认真看过官方文档,就能顺利的进行部署。
需要注意的细节,写最前面了
1,本地没有build镜像,使用的是官方镜像:
docker pull ghcr.io/mastodon/mastodon
2,networks与官方不同,因为我本地容器服务internal_、external_被占用了。另外traefik网络是为了与反向代理服务进行互通。不了解的可以参考以前文章
官方:
1networks:
2 - internal_network
3 - external_network
本地配置:
1networks:
2 - mastodon_networks
3 - traefik
3,一定要保证容器之间是互通的,否则找不到服务,会导致启动失败。
4,.env.production 配置文件在初始化安装的时候不需要引入!
5,创建网卡
1docker network create mastodon_networks
1,使用官方docker-compose进行配置拆分
官方docker-compose配置、官方README 根据官方的配置文件共分为db、es、web、streaming、sidekiq5个服务融合在一起,不利于后期维护和服务更新。下面进行配置拆分。共拆分为4个服务。
1.1,PostgreSQL 配置
保存以下配置文件名为:docker-compose.postgresql.yml
1version: '3'
2services:
3 postgresql:
4 restart: always
5 image: postgres:14-alpine
6 shm_size: 256mb
7 # 可视化连接使用
8 ports:
9 - 54322:5432
10 networks:
11 - mastodon_networks
12 healthcheck:
13 test: ['CMD', 'pg_isready', '-U', 'postgres']
14 volumes:
15 - ./postgres14:/var/lib/postgresql/data
16 environment:
17 POSTGRES_HOST_AUTH_METHOD: trust
18 # 设置个密码 可视化工具连接使用
19 POSTGRESQL_PASSWORD: bitnami1
20networks:
21 mastodon_networks:
22 external: true
1.2,Redis 配置
保存以下配置文件名为:docker-compose.redis.yml
1version: '3'
2services:
3 redis:
4 restart: always
5 image: redis:7-alpine
6 healthcheck:
7 test: ['CMD', 'redis-cli', 'ping']
8 volumes:
9 - ./redis:/data
10 networks:
11 - mastodon_networks
12networks:
13 mastodon_networks:
14 external: true
15
1.3,Elasticsearch 配置
保存以下配置文件名为:docker-compose.elasticsearch.yml
1version: '3'
2
3services:
4 elasticsearch:
5 restart: always
6 image: docker.elastic.co/elasticsearch/elasticsearch:7.17.4
7 environment:
8 - "ES_JAVA_OPTS=-Xms512m -Xmx512m -Des.enforce.bootstrap.checks=true"
9 - "xpack.license.self_generated.type=basic"
10 - "xpack.security.enabled=false"
11 - "xpack.watcher.enabled=false"
12 - "xpack.graph.enabled=false"
13 - "xpack.ml.enabled=false"
14 - "bootstrap.memory_lock=true"
15 - "cluster.name=es-mastodon"
16 - "discovery.type=single-node"
17 - "thread_pool.write.queue_size=1000"
18 networks:
19 - mastodon_networks
20 healthcheck:
21 test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"]
22 volumes:
23 - ./elasticsearch:/usr/share/elasticsearch/data
24 ulimits:
25 memlock:
26 soft: -1
27 hard: -1
28 nofile:
29 soft: 65536
30 hard: 65536
31 ports:
32 - '9200:9200'
33
34networks:
35 mastodon_networks:
36 external: true
1.4,服务web、streaming、sidekiq的配置
.env.production.sample 复制文件内容并保存为:.env.production
保存以下配置文件名为:docker-compose.start.yml
1version: '3'
2services:
3 web:
4 image: ghcr.io/mastodon/mastodon
5 restart: always
6 env_file: .env.production
7 environment:
8 RAILS_ENV: production
9 command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
10 healthcheck:
11 # prettier-ignore
12 test:
13 [
14 'CMD-SHELL',
15 'wget -q --spider --proxy=off localhost:3000/health || exit 1'
16 ]
17 volumes:
18 - ./public/system:/mastodon/public/system
19 networks:
20 - mastodon_networks
21 - traefik
22 streaming:
23 image: ghcr.io/mastodon/mastodon
24 restart: always
25 env_file: .env.production
26 command: node ./streaming
27 environment:
28 - "NODE_ENV=production"
29 healthcheck:
30 # prettier-ignore
31 test:
32 [
33 'CMD-SHELL',
34 'wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1'
35 ]
36 networks:
37 - mastodon_networks
38 - traefik
39 sidekiq:
40 image: ghcr.io/mastodon/mastodon
41 restart: always
42 env_file: .env.production
43 environment:
44 - "RAILS_ENV=production"
45 command: bundle exec sidekiq
46 networks:
47 - mastodon_networks
48 - traefik
49 volumes:
50 - ./public/system:/mastodon/public/system
51 healthcheck:
52 test: [ 'CMD-SHELL', "ps aux | grep '[s]idekiq 6' || false" ]
53
54networks:
55 mastodon_networks:
56 external: true
57 traefik:
58 external: true
1.5,配置前端代理服务
NGINX配置参考官方配置nginx-configuration,删除了一下其他配置。修改了client_max_body_size为100,解决上传大图片返回413错误。(自行调整)
保存以下配置文件名为:docker-compose.index.yml
1version: "3.6"
2services:
3 mastodon-halobug:
4 image: nginx:1.21.4-alpine
5 restart: always
6 expose:
7 - 80
8 volumes:
9 - /etc/localtime:/etc/localtime:ro
10 - /etc/timezone:/etc/timezone:ro
11 - ./nginx.index.conf:/etc/nginx/conf.d/default.conf
12 networks:
13 - traefik
14 - mastodon_networks
15 labels:
16 - "traefik.enable=true"
17 - "traefik.docker.network=traefik"
18 - "traefik.http.routers.mastodon-halobug.entrypoints=https"
19 - "traefik.http.routers.mastodon-halobug.tls=true"
20 - "traefik.http.routers.mastodon-halobug.rule=Host(`chat.halobug.cn`)"
21 - "traefik.http.services.mastodon-halobug-backend.loadbalancer.server.scheme=http"
22 - "traefik.http.services.mastodon-halobug-backend.loadbalancer.server.port=80"
23 logging:
24 driver: "json-file"
25 options:
26 max-size: "1m"
27networks:
28 mastodon_networks:
29 external: true
30 traefik:
31 external: true
保存以下配置文件名为:nginx.index.conf
1map $http_upgrade $connection_upgrade {
2 default upgrade;
3 '' close;
4}
5server {
6 listen 80;
7 server_name default_server;
8 keepalive_timeout 70;
9 sendfile on;
10 client_max_body_size 100m;
11
12 root /home/mastodon/live/public;
13
14 gzip on;
15 gzip_disable "msie6";
16 gzip_vary on;
17 gzip_proxied any;
18 gzip_comp_level 6;
19 gzip_buffers 16 8k;
20 gzip_http_version 1.1;
21 gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
22
23 add_header Strict-Transport-Security "max-age=31536000";
24
25 location / {
26 try_files $uri @proxy;
27 }
28
29 location ~ ^/(emoji|packs|system/accounts/avatars|system/media_attachments/files) {
30 add_header Cache-Control "public, max-age=31536000, immutable";
31 try_files $uri @proxy;
32 }
33
34 location /sw.js {
35 add_header Cache-Control "public, max-age=0";
36 try_files $uri @proxy;
37 }
38
39 location @proxy {
40 proxy_set_header Host $host;
41 proxy_set_header X-Real-IP $remote_addr;
42 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
43 proxy_set_header X-Forwarded-Proto "https";
44 proxy_set_header Proxy "";
45 proxy_pass_header Server;
46
47 proxy_pass http://web:3000;
48 proxy_buffering on;
49 proxy_redirect off;
50 proxy_http_version 1.1;
51 proxy_set_header Upgrade $http_upgrade;
52 proxy_set_header Connection $connection_upgrade;
53
54 tcp_nodelay on;
55 }
56
57 location /api/v1/streaming {
58 proxy_set_header Host $host;
59 proxy_set_header X-Real-IP $remote_addr;
60 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
61 proxy_set_header X-Forwarded-Proto "https";
62 proxy_set_header Proxy "";
63
64 proxy_pass http://streaming:4000;
65 proxy_buffering off;
66 proxy_redirect off;
67 proxy_http_version 1.1;
68 proxy_set_header Upgrade $http_upgrade;
69 proxy_set_header Connection $connection_upgrade;
70
71 tcp_nodelay on;
72 }
73}
2,搭建文件存储服务
2.1,运行Minio
保存以下配置文件名为:docker-compose.minio.yml
1version: "3"
2
3services:
4
5 mastodon-minio-nginx:
6 image: nginx:1.21.4-alpine
7 volumes:
8 - ./nginx.minio.conf:/etc/nginx/conf.d/default.conf:ro
9 expose:
10 - 80
11 environment:
12 - NGINX_HOST=localhost
13 - NGINX_PORT=80
14 networks:
15 - traefik
16 - mastodon_networks
17 labels:
18 - "traefik.enable=true"
19 - "traefik.docker.network=traefik"
20 - "traefik.http.routers.mastodon-oss-http.entrypoints=http"
21 - "traefik.http.routers.mastodon-oss-http.rule=Host(`oss.halobug.cn`)"
22 - "traefik.http.routers.mastodon-oss-https.entrypoints=https"
23 - "traefik.http.routers.mastodon-oss-https.tls=true"
24 - "traefik.http.routers.mastodon-oss-https.rule=Host(`oss.halobug.cn`)"
25 - "traefik.http.services.mastodon-oss-backend.loadbalancer.server.scheme=http"
26 - "traefik.http.services.mastodon-oss-backend.loadbalancer.server.port=80"
27 depends_on:
28 - minio
29 minio:
30 image: minio/minio:RELEASE.2022-01-08T03-11-54Z
31 volumes:
32 - ./minio/data:/data:z
33 command: minio server /data --address 0.0.0.0:80 --listeners 1 --console-address 0.0.0.0:9001
34 environment:
35 MINIO_ROOT_USER: umf3V1C3Hu5TzCDDqIXFbDDviYGhV627
36 MINIO_ROOT_PASSWORD: OqIwA1GJADWgCf5yvlRTKTJ6bTYAhaO9exqX5lo3GlOlLfVcIbn4v2CsuamB
37 MINIO_REGION_NAME: cn-homelab-1
38 MINIO_BROWSER: on
39 MINIO_BROWSER_REDIRECT_URL: https://mastodon-s3.halobug.cn
40 MINIO_PROMETHEUS_AUTH_TYPE: public
41 restart: always
42 ports:
43 - 9001:9001
44 expose:
45 - 80
46 networks:
47 - traefik
48 - mastodon_networks
49 labels:
50 - "traefik.enable=true"
51 - "traefik.docker.network=traefik"
52 - "traefik.http.middlewares.minio-gzip.compress=true"
53 - "traefik.http.routers.minio-admin.middlewares=minio-gzip"
54 - "traefik.http.routers.minio-admin.entrypoints=https"
55 - "traefik.http.routers.minio-admin.tls=true"
56 - "traefik.http.routers.minio-admin.rule=Host(`mastodon-s3.halobug.cn`)"
57 - "traefik.http.routers.minio-admin.service=minio-admin-backend"
58 - "traefik.http.services.minio-admin-backend.loadbalancer.server.scheme=http"
59 - "traefik.http.services.minio-admin-backend.loadbalancer.server.port=80"
60 healthcheck:
61 test: ["CMD", "curl", "-f", "http://localhost:80/minio/health/live"]
62 interval: 3s
63 retries: 12
64 logging:
65 driver: "json-file"
66 options:
67 max-size: "10m"
68networks:
69 traefik:
70 external: true
71 mastodon_networks:
72 external: true
保存以下配置文件名为:nginx.minio.conf
1server {
2 listen 80;
3 server_name localhost;
4
5 keepalive_timeout 70;
6 sendfile on;
7 client_max_body_size 80m;
8
9 location / {
10 proxy_set_header X-Real-IP $remote_addr;
11 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
12 proxy_set_header X-Forwarded-Proto $scheme;
13 proxy_set_header Host $http_host;
14
15 proxy_connect_timeout 300;
16 proxy_http_version 1.1;
17 proxy_set_header Connection "";
18 chunked_transfer_encoding off;
19
20 proxy_pass http://minio/mastodon/;
21 }
22
23 location /health {
24 access_log off;
25 return 200 "ok";
26 }
27}
运行minio
1 docker-compose -f docker-compose.minio.yml up -d
2.2,初始化Minio
保存以下配置文件名为:docker-compose.minio.init.yml
1version: "3"
2services:
3
4 minio-client:
5 image: minio/mc:RELEASE.2022-01-07T06-01-38Z
6 entrypoint: >
7 /bin/sh -c "
8 /usr/bin/mc config host rm local;
9 /usr/bin/mc config host add --quiet --api s3v4 local http://minio umf3V1C3Hu5TzCDDqIXFbDDviYGhV627 OqIwA1GJADWgCf5yvlRTKTJ6bTYAhaO9exqX5lo3GlOlLfVcIbn4v2CsuamB;
10 /usr/bin/mc mb --quiet local/mastodon/;
11 /usr/bin/mc policy set public local/mastodon;
12 "
13 networks:
14 - traefik
15
16networks:
17 traefik:
18 external: true
运行命令(运行一次即可)
1 docker-compose -f docker-compose.minio.init.yml up
本地绑定hosts
1127.0.0.1 mastodon-s3.halobug.cn oss.halobug.cn
浏览器访问 http://127.0.0.1:9001
初始化完成后查看Buckets
到此存储服务部署完成,下面开始启动基础服务。
所有配置文件
3,启动基础服务
3.1,运行PostgreSQL
1docker-compose -f docker-compose.postgresql.yml up -d
3.2,运行Redis
1docker-compose -f docker-compose.redis.yml up -d
3.3,运行Elasticsearch
1docker-compose -f docker-compose.elasticsearch.yml up -d
全部使用官方镜像,启动成功后如下图所示:
4,安装Mastodon
4.1,容器内执行安装命令
上一步已经说了,安装的注意事项。再次提醒心急的同学们。
1.env.production 配置文件在初始化安装的时候不需要引入
执行安装命令:
1docker-compose -f docker-compose.start.yml run --rm web bundle exec rake mastodon:setup
按照安装引导进行配置
安装完成后的配置
1# Generated with mastodon:setup on 2023-07-13 04:02:06 UTC
2
3# Some variables in this file will be interpreted differently whether you are
4# using docker-compose or not.
5
6LOCAL_DOMAIN=chat.halobug.cn
7SINGLE_USER_MODE=false
8SECRET_KEY_BASE=d2f61bffbf601042a51bbbae7732ebb93a5803ac40713e3275220aa5894d1132bd4e0870c4fa3f17f99f5d7e06e7c83a46ec0f31b31c60b38242d8d07f042b96
9OTP_SECRET=cecbae5d4595c57299b3d30eabc21f8c16c54d508a66547bbff107ad6d029a9129c252067aae6b9b725c7ce547a68b65a1eff5fc34efb112a35089fab193820d
10VAPID_PRIVATE_KEY=9G4BjizL7_qyW8IwDhF-ILX_fdURffERFK8HT7sGrOs=
11VAPID_PUBLIC_KEY=BIuyba_wWuguaTSZMqiFPOd6CzIv3wHKwdiD38oeOm5_IYfFIC0F3YOK7Muh7XO2EwLf3Og0ToprvQ-lejhsEpk=
12DB_HOST=postgresql
13DB_PORT=5432
14DB_NAME=postgres
15DB_USER=postgres
16DB_PASS=bitnami1
17REDIS_HOST=redis
18REDIS_PORT=6379
19REDIS_PASSWORD=
20SMTP_SERVER=smtp.mailgun.org
21SMTP_PORT=587
22SMTP_LOGIN=
23SMTP_PASSWORD=
24SMTP_AUTH_METHOD=plain
25SMTP_OPENSSL_VERIFY_MODE=none
26SMTP_ENABLE_STARTTLS=auto
27SMTP_FROM_ADDRESS=Mastodon <notifications@chat.halobug.cn>
之后你会发现运行有个异常,因为docker-compose.start.yml文件里还有streaming、sidekiq这两个服务。并且到此使用的还是官方默认的配置文件、找不到对应的基础服务造成的。按照输出的配置重新修改即可。
4.2,将安装后配置参数值,复制至官方配置文件中
需要注意的是,安装引导没有Elasticsearch的指导。在配置文件中加上即可,ES_USER、ES_PASS设为空。
SMTP配置:我有阿里云服务所以直接配置了。(你也可以自己申请SMTP,自己搜索吧)
4.3,S3存储配置
1S3_ENABLED=true
2S3_PROTOCOL=https
3S3_BUCKET=mastodon
4S3_REGION=cn-homelab-1
5S3_ALIAS_HOST=oss.halobug.cn
6S3_ENDPOINT=https://mastodon-s3.halobug.cn
7AWS_ACCESS_KEY_ID=umf3V1C3Hu5TzCDDqIXFbDDviYGhV627
8AWS_SECRET_ACCESS_KEY=OqIwA1GJADWgCf5yvlRTKTJ6bTYAhaO9exqX5lo3GlOlLfVcIbn4v2CsuamB
因为是单机部署,容器间通讯用无法使用https,所以在docker-compose.start.yml中web、streaming、sidekiq 配置中增加extra_hosts。192.168.12.89 为局域网IP。
1 extra_hosts:
2 - "mastodon-s3.halobug.cn:192.168.12.89"
配置参考图:
4.4,将env_file的注释“打开”
4.1注释了配置文件,现在重新“打开”
之后进入启动服务的流程
5,启动服务
5.1,运行Mastodon
启动命令:
1docker-compose -f docker-compose.start.yml up -d
查看日志:
1docker-compose -f docker-compose.start.yml logs -f
启动后如图所示
正常运行后,还差最后一步,即可对外提供服务。
5.2,启动 docker-compose.index.yml
自行配置https,可参考以前文章。
启动命令:
1docker-compose -f docker-compose.index.yml up -d
本地绑定hosts。
1127.0.0.1 chat.halobug.cn
6,注册使用
6.1,访问
浏览器访问 https://chat.halobug.cn
6.2,注册账号进行测试
6.3,邮件验证
过不了多久就收到一封邮件进行确认。
6.4,点开邮件中的连接,验证即可。成功后的页面
6.5,发布你的第一条动态吧。你好,世界!
到此服务搭建成功。