如何在 Rocky Linux 9 上使用 Docker 安装 Mastodon 社交网络
在此页
- 先决条件
- 第 1 步 - 配置防火墙
- 第 2 步 - 安装 Docker 和 Docker Compose
- 第 3 步 - 准备安装
- 第 4 步 - 安装 Mastodon
- 创建目录并设置所有权
- 创建环境和 docker compose 文件
- 创建应用程序机密
- Mastodon 环境文件
- 准备乳齿象
- Tootctl CLI 工具
- Mastodon 服务文件
- 初始化搜索
- 额外的助手服务
- 访问 Mastodon
Mastodon 是一个免费、去中心化和开源的社交网络。它是作为 Twitter 的替代品而创建的。就像 Twitter 一样,人们可以互相关注,并发布消息、图像和视频。但与 Twitter 不同的是,内容没有中央存储或授权。
相反,Mastodon 在数千个不同的服务器上运行,每个服务器由社区的不同成员运行。在一个服务器上注册的用户可以轻松连接到另一个网络上的用户,并跨实例相互关注。
任何人都可以安装他们的 Mastodon 服务器实例。本教程将教您如何使用 Docker 在装有 Rocky Linux 9 的服务器上设置您的 Mastodon 实例。 Docker 通过包含容器中所需的所有包和服务,使安装 Mastodon 变得容易。
先决条件
-
A server running Rocky Linux 9 with a minimum of 2 CPU cores and 2GB of memory. You will need to upgrade the server as per requirements.
-
A non-root user with sudo privileges.
-
A fully qualified domain name (FQDN) pointing to your server. For our purposes, we will use
mastodon.example.com
as the domain name. -
Mastodon sends email notifications to users. We will recommend you use a 3rd party Transactional mail service like Mailgun, Sendgrid, Amazon SES, or Sparkpost. The instructions in the guide will be using Amazon SES.
-
Make sure everything is updated.
$ sudo dnf update
-
Install basic utility packages. Some of them may already be installed.
$ sudo dnf install wget curl nano unzip yum-utils -y
第 1 步 - 配置防火墙
第一步是配置防火墙。 Rocky Linux 使用 Firewalld 防火墙。检查防火墙状态。
$ sudo firewall-cmd --state running
防火墙适用于不同的区域,公共区域是我们将使用的默认区域。列出防火墙上所有活动的服务和端口。
$ sudo firewall-cmd --permanent --list-services
它应该显示以下输出。
cockpit dhcpv6-client ssh
Wiki.js 需要 HTTP 和 HTTPS 端口才能运行。打开它们。
$ sudo firewall-cmd --permanent --add-service=http $ sudo firewall-cmd --permanent --add-service=https
添加伪装,因为应用程序将联系其他实例。
$ sudo firewall-cmd --permanent --add-masquerade
重新加载防火墙以应用更改。
$ sudo firewall-cmd --reload
第 2 步 - 安装 Docker 和 Docker Compose
Rocky Linux 附带旧版本的 Docker。要安装最新版本,首先,安装官方 Docker 存储库。
$ sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
安装最新版本的 Docker。
$ sudo dnf install docker-ce docker-ce-cli containerd.io
在尝试安装 Docker 时,您可能会遇到以下错误。
ror: Problem: problem with installed package buildah-1:1.26.2-1.el9_0.x86_64 - package buildah-1:1.26.2-1.el9_0.x86_64 requires runc >= 1.0.0-26, but none of the providers can be installed - package containerd.io-1.6.9-3.1.el9.x86_64 conflicts with runc provided by runc-4:1.1.3-2.el9_0.x86_64 - package containerd.io-1.6.9-3.1.el9.x86_64 obsoletes runc provided by runc-4:1.1.3-2.el9_0.x86_64 - cannot install the best candidate for the job
如果出现上述错误,请使用以下命令。
$ sudo dnf install docker-ce docker-ce-cli containerd.io docker-compose-plugin --allowerasing
启用并运行 Docker 守护进程。
$ sudo systemctl enable docker --now
验证它是否正在运行。
? docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled) Active: active (running) since Sat 2022-11-12 00:19:44 UTC; 6s ago TriggeredBy: ? docker.socket Docs: https://docs.docker.com Main PID: 99263 (dockerd) Tasks: 8 Memory: 28.1M CPU: 210ms CGroup: /system.slice/docker.service ??99263 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
默认情况下,Docker 需要 root 权限。如果您想避免每次运行
docker
命令时都使用sudo
,请将您的用户名添加到docker
组。$ sudo usermod -aG docker $(whoami)
您将需要注销服务器并以同一用户身份重新登录以启用此更改或使用以下命令。
$ su - ${USER}
确认您的用户已添加到 Docker 组。
$ groups navjot wheel docker
第 3 步 - 准备安装
对于 Elasticsearch,mmap 计数的默认限制非常低。运行以下命令来检查默认值。
$ sysctl vm.max_map_count
您将获得以下输出。
vm.max_map_count = 65530
使用以下命令增加该值。
$ echo "vm.max_map_count=262144" | sudo tee /etc/sysctl.d/90-max_map_count.conf $ sudo sysctl --load /etc/sysctl.d/90-max_map_count.conf
配置 SELinux 以允许网络连接。
$ sudo setsebool -P httpd_can_network_connect 1
第 4 步 - 安装 Mastodon
创建目录并设置所有权
为 Mastodon 和相关服务创建目录。
$ sudo mkdir -p /opt/mastodon/database/{postgresql,pgbackups,redis,elasticsearch} $ sudo mkdir -p /opt/mastodon/web/{public,system} $ sudo mkdir -p /opt/mastodon/branding
为 Elasticsearch、Web 和备份目录设置适当的所有权。
$ sudo chown 991:991 /opt/mastodon/web/{public,system} $ sudo chown 1000 /opt/mastodon/database/elasticsearch $ sudo chown 70:70 /opt/mastodon/database/pgbackups
切换到 Mastodon 目录。
$ cd /opt/mastodon
创建环境和 docker compose 文件
为应用程序和数据库创建环境文件。
$ sudo touch application.env database.env
创建并打开 Docker 组合文件以进行编辑。
$ sudo nano docker-compose.yml
将以下代码粘贴到其中。
version: '3' services: postgresql: image: postgres:15-alpine env_file: database.env restart: always shm_size: 512mb healthcheck: test: ['CMD', 'pg_isready', '-U', 'postgres'] volumes: - postgresql:/var/lib/postgresql/data - pgbackups:/backups networks: - internal_network redis: image: redis:7-alpine restart: always healthcheck: test: ['CMD', 'redis-cli', 'ping'] volumes: - redis:/data networks: - internal_network redis-volatile: image: redis:7-alpine restart: always healthcheck: test: ['CMD', 'redis-cli', 'ping'] networks: - internal_network elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:7.17.7 restart: always env_file: database.env environment: - cluster.name=elasticsearch-mastodon - discovery.type=single-node - bootstrap.memory_lock=true - xpack.security.enabled=true - ingest.geoip.downloader.enabled=false ulimits: memlock: soft: -1 hard: -1 healthcheck: test: ["CMD-SHELL", "nc -z elasticsearch 9200"] volumes: - elasticsearch:/usr/share/elasticsearch/data networks: - internal_network website: image: tootsuite/mastodon:v4.0.2 env_file: - application.env - database.env command: bash -c "bundle exec rails s -p 3000" restart: always depends_on: - postgresql - redis - redis-volatile - elasticsearch ports: - '127.0.0.1:3000:3000' networks: - internal_network - external_network healthcheck: test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:3000/health || exit 1'] volumes: - uploads:/mastodon/public/system shell: image: tootsuite/mastodon:v4.0.2 env_file: - application.env - database.env command: /bin/bash restart: "no" networks: - internal_network - external_network volumes: - uploads:/mastodon/public/system - static:/static streaming: image: tootsuite/mastodon:v4.0.2 env_file: - application.env - database.env command: node ./streaming restart: always depends_on: - postgresql - redis - redis-volatile - elasticsearch ports: - '127.0.0.1:4000:4000' networks: - internal_network - external_network healthcheck: test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1'] sidekiq: image: tootsuite/mastodon:v4.0.2 env_file: - application.env - database.env command: bundle exec sidekiq restart: always depends_on: - postgresql - redis - redis-volatile - website networks: - internal_network - external_network healthcheck: test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"] volumes: - uploads:/mastodon/public/system networks: external_network: internal_network: #internal:true volumes: postgresql: driver_opts: type: none device: /opt/mastodon/database/postgresql o: bind pgbackups: driver_opts: type: none device: /opt/mastodon/database/pgbackups o: bind redis: driver_opts: type: none device: /opt/mastodon/database/redis o: bind elasticsearch: driver_opts: type: none device: /opt/mastodon/database/elasticsearch o: bind uploads: driver_opts: type: none device: /opt/mastodon/web/system o: bind static: driver_opts: type: none device: /opt/mastodon/web/public o: bind
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
在编写本教程时,Mastodon 的最新可用版本是 v4.0.2。查看 Mastodon GitHub Releases 页面并适当调整 Docker compose 文件中的版本。我们还使用最新版本的 PostgreSQL 和 Redis。您可以根据您的要求调整它们。我们目前正在使用 Elasticsearch 7.x。您可以在 Docker Hub 页面上关注 Elasticsearch 的主要版本,因此您必须不断手动更新它以获取与 Java 相关的安全更新。
internal: true
不适用于 firewalld,这就是它在上面的文件中被注释掉的原因。如果此问题得到解决,您可以重新添加该附加限制。创建应用程序机密
下一步是创建应用程序秘密值。
通过运行以下命令两次生成
SECRET_KEY_BASE
和OTP_SECRET
值。第一次需要一些时间,因为它会拉取图像。$ docker compose run --rm shell bundle exec rake secret
您也可以使用
openssl
实用程序。$ openssl rand -hex 64
使用以下命令生成
VAPID_PRIVATE_KEY
和VAPID_PUBLIC_KEY
值。$ docker compose run --rm shell bundle exec rake mastodon:webpush:generate_vapid_key
您将获得类似的输出。
VAPID_PRIVATE_KEY=u2qsCs5JdmdmMLnUuU0sgmFGvZedteJz-lFB_xF4_ac= VAPID_PUBLIC_KEY=BJXjE2hIXvFpo6dnHqyf1i-2PcP-cBoL95UCmhhxwlAgtFw_vnrYp4GBneR7_cmI9LZUYjHFh-TBAPSb9WTqH9A=
使用
openssl
实用程序生成 PostgreSQL 和 Elasticsearch 密码。$ openssl rand -hex 15
Mastodon 环境文件
打开
application.env
文件进行编辑。$ sudo nano application.env
在其中粘贴以下行。
# environment RAILS_ENV=production NODE_ENV=production # domain LOCAL_DOMAIN=mastodon.example.com # redirect to the first profile SINGLE_USER_MODE=false # do not serve static files RAILS_SERVE_STATIC_FILES=false # concurrency WEB_CONCURRENCY=2 MAX_THREADS=5 # pgbouncer #PREPARED_STATEMENTS=false # locale DEFAULT_LOCALE=en # email, not used SMTP_SERVER=email-smtp.us-west-2.amazonaws.com SMTP_PORT=587 SMTP_LOGIN=AKIA3FIG4NVFNSC3AHXE SMTP_PASSWORD=BHM4MVOjBmnGhSJ9lH3PAXKJ/9AiLWcUghG/kEN2kkFo # secrets SECRET_KEY_BASE=c09fa403575e0b431e54a2e228f20cd5a5fdfdbba0da80598959753b829a4e3c0266eedbac7e3cdf9f3345db36c56302c0e1bc5bfc8c5d516be59a2c41de7e37 OTP_SECRET=febb7dbb0d3308094083733fc923a430e52ccec767d48d7d2e0c577bfcb6863dbdfc920b1004b1f8c2967b9866bd7a0b4a15460f9fc7687aa4a42acf54e5a3d4 # Changing VAPID keys will break push notifications VAPID_PRIVATE_KEY=13RgrfOY2tkwuUycylDPOkoHennkJ0ZAPV_fUwDy7-g= VAPID_PUBLIC_KEY=BDAQuGwPbh1kbCV904adYXHvz9lLRaJHkiQkihRDPyBn3QmkAYbR21WHYoP8TkyG6dylG6IXpEVfLwdoW7fJVns=
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
打开
database.env
文件进行编辑。$ sudo nano database.env
在其中粘贴以下行。
# postgresql configuration POSTGRES_USER=mastodon POSTGRES_DB=mastodon POSTGRES_PASSWORD=15ff12dcb93aa60680d2aadb4032ee PGPASSWORD=15ff12dcb93aa60680d2aadb4032ee PGPORT=5432 PGHOST=postgresql PGUSER=mastodon # pgbouncer configuration #POOL_MODE=transaction #ADMIN_USERS=postgres,mastodon #DATABASE_URL="postgres://mastodon::5432/mastodon" # elasticsearch ES_JAVA_OPTS=-Xms512m -Xmx512m ELASTIC_PASSWORD=13382e99f6b2d4dc7f3d66e4b9872d # mastodon database configuration #DB_HOST=pgbouncer DB_HOST=postgresql DB_USER=mastodon DB_NAME=mastodon DB_PASS=15ff12dcb93aa60680d2aadb4032ee DB_PORT=5432 REDIS_HOST=redis REDIS_PORT=6379 CACHE_REDIS_HOST=redis-volatile CACHE_REDIS_PORT=6379 ES_ENABLED=true ES_HOST=elasticsearch ES_PORT=9200 ES_USER=elastic ES_PASS=13382e99f6b2d4dc7f3d66e4b9872d
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
准备乳齿象
准备好 Nginx 提供的静态文件。
$ docker compose run --rm shell bash -c "cp -r /opt/mastodon/public/* /static/"
调出数据层。
$ docker compose up -d postgresql redis redis-volatile
检查容器的状态。
$ watch docker compose ps
等待
running (healthy)
,然后按Ctrl + C
并使用以下命令初始化数据库。$ docker compose run --rm shell bundle exec rake db:setup
第 5 步 - 安装 Nginx
Rocky Linux 附带旧版本的 Nginx。您需要下载官方 Nginx 存储库以安装最新版本。
创建并打开
/etc/yum.repos.d/nginx.repo
文件以创建官方 Nginx 存储库。$ sudo nano /etc/yum.repos.d/nginx.repo
将以下代码粘贴到其中。
[nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true [nginx-mainline] name=nginx mainline repo baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck=1 enabled=0 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
安装 Nginx 服务器。
$ sudo dnf install nginx
验证安装。
$ nginx -v nginx version: nginx/1.22.1
启用并启动 Nginx 服务器。
$ sudo systemctl enable nginx --now
检查服务器的状态。
$ sudo systemctl status nginx ? nginx.service - nginx - high performance web server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled) Active: active (running) since Sun 2022-11-13 13:49:55 UTC; 1s ago Docs: http://nginx.org/en/docs/ Process: 230797 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS) Main PID: 230798 (nginx) Tasks: 3 (limit: 12355) Memory: 2.8M CPU: 13ms CGroup: /system.slice/nginx.service ??230798 "nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf" ??230799 "nginx: worker process" ??230800 "nginx: worker process"
第 6 步 - 安装 SSL
Certbot 工具使用 Lets Encrypt API 生成 SSL 证书。它需要 EPEL 存储库才能工作。
$ sudo dnf install epel-release
我们将使用 Snapd 安装 Certbot。安装快照。
$ sudo dnf install snapd
启用并启动 Snap 服务。
$ sudo systemctl enable snapd --now
安装 Snap 核心包。
$ sudo snap install core $ sudo snap refresh core
为 Snapd 工作创建必要的链接。
$ sudo ln -s /var/lib/snapd/snap /snap $ echo 'export PATH=$PATH:/var/lib/snapd/snap/bin' | sudo tee -a /etc/profile.d/snapd.sh
发出以下命令以安装 Certbot。
$ sudo snap install --classic certbot
通过创建指向其可执行文件的符号链接来启用 Certbot。
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
生成 SSL 证书。
$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m -d mastodon.example.com
上面的命令会将证书下载到服务器上的
/etc/letsencrypt/live/mastodon.example.com
目录。生成 Diffie-Hellman 组证书。
$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
要检查 SSL 续订是否正常工作,请试运行该过程。
$ sudo certbot renew --dry-run
如果您没有看到任何错误,则一切就绪。您的证书将自动更新。
第 7 步 - 配置 Nginx
打开文件
/etc/nginx/nginx.conf
进行编辑。$ sudo nano /etc/nginx/nginx.conf
在行
include /etc/nginx/conf.d/*.conf;
之前添加以下行。server_names_hash_bucket_size 64;
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
创建并打开文件
/etc/nginx/conf.d/mastodon.conf
进行编辑。$ sudo nano /etc/nginx/conf.d/mastodon.conf
将以下代码粘贴到其中。
map $http_upgrade $connection_upgrade { default upgrade; '' close; } upstream backend { server 127.0.0.1:3000 fail_timeout=0; } upstream streaming { server 127.0.0.1:4000 fail_timeout=0; } proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g; server { listen 80 default_server; server_name mastodon.example.com; location / { return 301 https://$host$request_uri; } } server { listen 443 ssl http2; server_name mastodon.example.com; access_log /var/log/nginx/mastodon.access.log; error_log /var/log/nginx/mastodon.error.log; http2_push_preload on; # Enable HTTP/2 Server Push ssl_certificate /etc/letsencrypt/live/mastodon.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/mastodon.example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/mastodon.example.com/chain.pem; ssl_session_timeout 1d; # Enable TLS versions (TLSv1.3 is required upcoming HTTP/3 QUIC). ssl_protocols TLSv1.2 TLSv1.3; # Enable TLSv1.3's 0-RTT. Use $ssl_early_data when reverse proxying to # prevent replay attacks. # # @see: https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data ssl_early_data on; ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384'; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; keepalive_timeout 70; sendfile on; client_max_body_size 80m; # OCSP Stapling --- # fetch OCSP records from URL in ssl_certificate and cache them ssl_stapling on; ssl_stapling_verify on; ssl_dhparam /etc/ssl/certs/dhparam.pem; add_header X-Early-Data $tls1_3_early_data; root /opt/mastodon/web/public; gzip on; gzip_disable "msie6"; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml image/x-icon; add_header Strict-Transport-Security "max-age=31536000" always; location / { try_files $uri @proxy; } location ~ ^/(system/accounts/avatars|system/media_attachments/files) { add_header Cache-Control "public, max-age=31536000, immutable"; add_header Strict-Transport-Security "max-age=31536000" always; root /opt/mastodon/; try_files $uri @proxy; } location ~ ^/(emoji|packs) { add_header Cache-Control "public, max-age=31536000, immutable"; add_header Strict-Transport-Security "max-age=31536000" always; try_files $uri @proxy; } location /sw.js { add_header Cache-Control "public, max-age=0"; add_header Strict-Transport-Security "max-age=31536000" always; try_files $uri @proxy; } location @proxy { 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; proxy_set_header Proxy ""; proxy_pass_header Server; proxy_pass http://backend; proxy_buffering on; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_cache CACHE; proxy_cache_valid 200 7d; proxy_cache_valid 410 24h; proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; add_header X-Cached $upstream_cache_status; add_header Strict-Transport-Security "max-age=31536000" always; tcp_nodelay on; } location /api/v1/streaming { 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; proxy_set_header Proxy ""; proxy_pass http://streaming; proxy_buffering off; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; tcp_nodelay on; } error_page 500 501 502 503 504 /500.html; } # This block is useful for debugging TLS v1.3. Please feel free to remove this # and use the `$ssl_early_data` variable exposed by NGINX directly should you # wish to do so. map $ssl_early_data $tls1_3_early_data { "~." $ssl_early_data; default ""; }
完成后,按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
验证 Nginx 配置文件语法。
$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
重新启动 Nginx 服务器。
$ sudo systemctl restart nginx
如果您收到以下错误,则很可能是由于 SELinux 限制。
nginx: [emerg] open() "/var/run/nginx.pid" failed (13: Permission denied)
要修复错误,请运行以下命令。
$ sudo ausearch -c 'nginx' --raw | audit2allow -M my-nginx $ sudo semodule -X 300 -i my-nginx.pp
再次启动 Nginx 服务。
$ sudo systemctl start nginx
第 8 步 - 启动 Mastodon
Tootctl CLI 工具
Tootctl CLI 工具用于在 Mastodon 上执行管理任务。我们需要使其在主机 shell 上可访问。
创建文件
/usr/local/bin/tootctl
并打开它进行编辑。$ sudo nano /usr/local/bin/tootctl
将以下代码粘贴到其中。
#!/bin/bash docker compose -f /opt/mastodon/docker-compose.yml run --rm shell tootctl ""
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
赋予文件可执行权限。
$ sudo chmod +x /usr/local/bin/tootctl
Mastodon 服务文件
您可以使用 Docker compose 命令启动 Mastodon 容器,但通过 systemd 单元文件更容易。
创建并打开 Mastodon 服务文件进行编辑。
$ sudo nano /etc/systemd/system/mastodon.service
将以下代码粘贴到其中。
[Unit] Description=Mastodon service After=docker.service [Service] Type=oneshot RemainAfterExit=yes WorkingDirectory=/opt/mastodon ExecStart=/usr/bin/docker compose -f /opt/mastodon/docker-compose.yml up -d ExecStop=/usr/bin/docker compose -f /opt/mastodon/docker-compose.yml down [Install] WantedBy=multi-user.target
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
重新加载系统守护进程以启动服务文件。
$ sudo systemctl daemon-reload
启用并启动 Mastodon 服务。
$ sudo systemctl enable --now mastodon.service
检查 Docker 容器的状态。
$ watch docker compose -f /opt/mastodon/docker-compose.yml ps
一旦容器的状态更改为
running (healthy)
,按 Ctrl + C 退出屏幕。为 Mastodon 创建管理员用户并记下提供的密码。
$ tootctl accounts create navjot --email --confirmed --role admin OK New password: 1338afbe1b4e06e823b6625da80cb537
如果要关闭用户注册,请使用以下命令。
$ tootctl settings registrations close
要再次打开注册,请发出以下命令。
$ tootctl settings registrations open
初始化搜索
在创建和填充 Elasticsearch 索引之前,您需要发出嘟嘟声。发出嘟嘟声后,发出以下命令。
$ tootctl search deploy
您可能会收到以下错误。
/opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/progress.rb:76:in `total=': You can't set the item's total value to less than the current progress. (ProgressBar::InvalidProgressError) from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/base.rb:178:in `block in update_progress' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/output.rb:43:in `with_refresh' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/base.rb:177:in `update_progress' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/base.rb:101:in `total=' from /opt/mastodon/lib/mastodon/search_cli.rb:67:in `deploy' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/invocation.rb:116:in `invoke' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor.rb:243:in `block in subcommand' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/base.rb:485:in `start' from /opt/mastodon/bin/tootctl:8:in `<main>'
在这种情况下,进入网站容器外壳。
$ docker exec -it mastodon-web-1 /bin/bash
运行以下命令。
$ sed -E 's/indices.sum.+/2000/g' -i lib/mastodon/search_cli.rb
退出容器外壳。
$ exit
再次运行 Elasticsearch 部署命令。
$ tootctl search deploy
额外的帮手服务
让我们创建另一个服务来删除下载的媒体文件。
创建并打开 Mastodon 媒体删除服务进行编辑。
$ sudo nano /etc/systemd/system/mastodon-media-remove.service
将以下代码粘贴到其中。
[Unit] Description=Mastodon - media remove service Wants=mastodon-media-remove.timer [Service] Type=oneshot StandardError=null StandardOutput=null WorkingDirectory=/opt/mastodon ExecStart=/usr/bin/docker compose -f /opt/mastodon/docker-compose.yml run --rm shell tootctl media remove [Install] WantedBy=multi-user.target
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
如果你想安排媒体删除,你可以为它设置一个定时器服务。
$ sudo nano /etc/systemd/system/mastodon-media-remove.timer
粘贴以下代码。
[Unit] Description=Schedule a media remove every week [Timer] Persistent=true OnCalendar=Sat *-*-* 00:00:00 Unit=mastodon-media-remove.service [Install] WantedBy=timers.target
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
您可以设置另一项服务来删除使用 OpenGraph 标签生成的 Rich 预览卡。
$ sudo nano /etc/systemd/system/mastodon-preview_cards-remove.service
粘贴以下代码。
[Unit] Description=Mastodon - preview cards remove service Wants=mastodon-preview_cards-remove.timer [Service] Type=oneshot StandardError=null StandardOutput=null WorkingDirectory=/opt/mastodon ExecStart=/usr/bin/docker compose -f /opt/mastodon/docker-compose.yml run --rm shell tootctl preview_cards remove [Install] WantedBy=multi-user.target
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
设置相应的定时服务。
$ sudo nano /etc/systemd/system/mastodon-preview_cards-remove.timer
粘贴以下代码。
[Unit] Description=Schedule a preview cards remove every week [Timer] Persistent=true OnCalendar=Sat *-*-* 00:00:00 Unit=mastodon-preview_cards-remove.service [Install] WantedBy=timers.target
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
重新加载系统守护进程。
$ sudo systemctl daemon-reload
启用并启动定时器。
$ sudo systemctl enable --now mastodon-preview_cards-remove.timer $ sudo systemctl enable --now mastodon-media-remove.timer
列出所有计时器以检查 Mastodon 服务的时间表。
$ systemctl list-timers
访问乳齿象
访问 URL
https://mastodon.example.com
来访问您的实例,您将看到一个类似的页面。在上面的屏幕截图中,您可以看到有 2 个用户,其中 1 个(我)被设置为管理员。通常情况并非如此。即使您创建了管理员帐户,它也不会在首次运行时显示在主页上。为此,请登录到您的实例,您将被带到以下页面。
单击右侧栏中的首选项选项以访问设置。从那里,单击左侧菜单中的“管理”选项以访问 Mastodons 管理面板。
单击左侧栏中的站点设置选项。
在这里,填写您的联系用户名和企业电子邮件,它们现在将反映在您的服务器主页上。还要填写各种其他信息,包括服务器描述、徽标和服务器规则,以自定义您的 Mastodon 实例。
第 9 步 - Mastodon 维护
要查看 Mastodon 实例的性能和日志,请转到
https://mastodon.example.com/sidekiq/
。您可以在此处查看与您的 Mastodon 实例相关的各种进程和计划任务的列表。您还可以在 Dead 或 Retries 部分下检查失败的任务。它还会告诉您实例的内存使用情况。
您可以从
https://mastodon.example.com/pghero/
检查实例数据库的健康状况。您可以执行数据库维护、运行 SQL 查询以及删除未使用的索引。要启用查询统计,请单击上述页面中的启用按钮,您将获得以下信息。
切换到根用户。
$ sudo -i su
切换到
/opt/mastodon/database/postgresql
目录。$ cd /opt/mastodon/database/postgresql
打开
postgresql.conf
文件。$ nano postgresql.conf
找到行
#shared_preload_libraries=# (change requires restart)
并将其替换为以下内容。shared_preload_libraries = 'pg_stat_statements'
在文件末尾添加以下行。
pg_stat_statements.track = all
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
重新启动 Mastodon 容器。
$ systemctl restart mastodon.service
退出根外壳。
$ exit
如果你检查数据库健康页面,你可以看到现在是否有任何慢查询。
注意:您还可以从首选项菜单启动 PgHero 和 Sidekiq URL。
如果您的站点由于某种原因没有加载,您可以检查 Docker 生成的日志。
$ docker logs <container-name>
第 10 步 - 备份 Mastodon
我们将使用名为 Restic 的第 3 方工具来备份 Mastodon。使用 Restic 备份的第一步是将所有文件和目录添加到存储库列表中。
创建并打开存储库列表文件以进行编辑。
$ sudo nano /opt/mastodon/backup-files
在其中粘贴以下行。
/etc/nginx /etc/letsencrypt /etc/systemd/system /root /opt/mastodon/database/pgbackups /opt/mastodon/*.env /opt/mastodon/docker-compose.yml /opt/mastodon/branding /opt/mastodon/database/redis /opt/mastodon/web/system /opt/mastodon/backup-files /opt/mastodon/mastodon-backup
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
安装 Restic。
$ sudo dnf install restic
创建备份存储库并创建初始备份。我们正在将数据备份到 S3 服务。
$ restic -r s3:https://$SERVER:$PORT/mybucket init $ restic -r s3:https://$SERVER:$PORT/mybucket backup $(cat /opt/mastodon/backup-files) --exclude /opt/mastodon/database/postgresql
创建 Mastodon 备份服务计时器并打开它进行编辑。
$ sudo nano /etc/systemd/system/mastodon-backup.timer
将以下代码粘贴到其中。
[Unit] Description=Schedule a mastodon backup every hour [Timer] Persistent=true OnCalendar=*:00:00 Unit=mastodon-backup.service [Install] WantedBy=timers.target
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
创建一个 Mastodon 备份服务文件并打开它进行编辑。
$ sudo nano /etc/systemd/system/mastodon-backup.service
将以下代码粘贴到其中。
[Unit] Description=Mastodon - backup service # Without this, they can run at the same time and race to docker compose, # double-creating networks and failing due to ambiguous network definition # requiring `docker network prune` and restarting After=mastodon.service [Service] Type=oneshot StandardError=file:/var/log/mastodon-backup.err StandardOutput=file:/var/log/mastodon-backup.log WorkingDirectory=/opt/mastodon ExecStart=/bin/bash /opt/mastodon/mastodon-backup [Install] WantedBy=multi-user.target
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
接下来,创建并打开
/opt/mastodon/mastodon-backup
文件进行编辑。这包含实际的备份命令。$ sudo nano /opt/mastodon/mastodon-backup
将以下代码粘贴到其中。
#!/bin/bash set -e AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= SERVER= PORT= RESTIC_PASSWORD_FILE=/root/restic-pasword docker compose -f /opt/mastodon/docker-compose.yml run --rm postgresql sh -c "pg_dump -Fp mastodon | gzip > /backups/dump.sql.gz" restic -r s3:https://$SERVER:$PORT/mybucket --cache-dir=/root backup $(cat /opt/mastodon/backup-files) --exclude /opt/mastodon/database/postgresql restic -r s3:https://$SERVER:$PORT/mybucket --cache-dir=/root forget --prune --keep-hourly 24 --keep-daily 7 --keep-monthly 3
通过按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
为备份脚本授予可执行权限。
$ sudo chmod +x /opt/mastodon/mastodon-backup
重新加载服务守护进程并启动备份服务和计时器。
$ sudo systemctl daemon-reload $ sudo systemctl enable --now mastodon-backup.service $ sudo systemctl enable --now mastodon-backup.timer
使用以下命令确认每小时备份正在进行并且可以访问。
$ restic -r s3:https://$SERVER:$PORT/mybucket snapshots $ restic -r s3:https://$SERVER:$PORT/mybucket mount /mnt
第 11 步 - 升级 Mastodon
升级 Mastodon 需要几个步骤。首先,切换到目录。
$ cd /opt/mastodon
拉取 Mastodon 的最新容器镜像。
$ docker compose pull
如果需要,可以在
docker-compose.yml
中进行任何更改。执行所有数据库迁移。
$ docker compose run --rm shell bundle exec rake db:migrate
更新静态文件的副本。
$ docker compose run --rm shell bash -c "cp -r /opt/mastodon/public/* /static/"
重新启动 Mastodon 容器。
$ sudo systemctl restart mastodon.service
以上说明为通用更新说明。始终检查 Mastodon 的 GitHub 发布页面,以查找版本之间的任何特定更新任务和命令,以确保一切顺利进行。
结论
我们关于在 Rocky Linux 9 服务器上使用 Docker 安装 Mastodon 社交网络的教程到此结束。如果您有任何问题,请在下面的评论中发表。