将mastodon实例迁移至docker容器内
2210年了,我怎么还在折腾长毛象。
最近计划把各种单独占着一个服务器的服务都容器化一下然后迁移到一个服务器上。不知不觉自己已经开了七八个服务器了,系统资源都没充分利用,放着久了也都是浪费钱。
备份原实例
首先按照官方迁移教程备份原实例,关闭服务后备份数据库、~/live/public/system以及~/live/.env.production。
用教程中的命令pg_dump -Fc mastodon_production -f backup.dump
即可备份数据库,文件backup.dump会生成于当前文件夹。
安装mastodon
安装docker和docker-compose后,将mastodon代码复制到本地,并切换到最新的稳定版:
git clone https://github.com/tootsuite/mastodon.git /mastodon
cd ~/mastodon
git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)
目前(2021年4月8日)稳定版3.3.0因为rails的一个依赖mimemagic 0.3.5被作者移除而无法正常build,暂时只能跳过git checkout,直接使用main branch,才可以正常build。
编辑docker-compose.yml,根据需要决定是否取消es的注释,在db下加入environment设置数据库名称及用户,并按照需求修改端口等:
version: '3'
services:
db:
restart: always
image: postgres:9.6-alpine
shm_size: 256mb
networks:
- internal_network
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres"]
volumes:
- ./postgres:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: mastodon
POSTGRES_DB: mastodon_production
POSTGRES_USER: mastodon
redis:
restart: always
image: redis:6.0-alpine
networks:
- internal_network
healthcheck:
test: ["CMD", "redis-cli", "ping"]
volumes:
- ./redis:/data
es:
restart: always
image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.8.10
environment:
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- "cluster.name=es-mastodon"
- "discovery.type=single-node"
- "bootstrap.memory_lock=true"
networks:
- internal_network
healthcheck:
test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"]
volumes:
- ./elasticsearch:/usr/share/elasticsearch/data
ulimits:
memlock:
soft: -1
hard: -1
web:
build: .
image: tootsuite/mastodon
restart: always
env_file: .env.production
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
networks:
- external_network
- internal_network
healthcheck:
test: ["CMD-SHELL", "wget -q --spider --proxy=off localhost:3000/health || exit 1"]
ports:
- "127.0.0.1:3000:3000"
depends_on:
- db
- redis
- es
volumes:
- ./public/system:/mastodon/public/system
streaming:
build: .
image: tootsuite/mastodon
restart: always
env_file: .env.production
command: node ./streaming
networks:
- external_network
- internal_network
healthcheck:
test: ["CMD-SHELL", "wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1"]
ports:
- "127.0.0.1:4000:4000"
depends_on:
- db
- redis
sidekiq:
build: .
image: tootsuite/mastodon
restart: always
env_file: .env.production
command: bundle exec sidekiq
depends_on:
- db
- redis
networks:
- external_network
- internal_network
volumes:
- ./public/system:/mastodon/public/system
## Uncomment to enable federation with tor instances along with adding the following ENV variables
## http_proxy=http://privoxy:8118
## ALLOW_ACCESS_TO_HIDDEN_SERVICE=true
# tor:
# image: sirboops/tor
# networks:
# - external_network
# - internal_network
#
# privoxy:
# image: sirboops/privoxy
# volumes:
# - ./priv-config:/opt/config
# networks:
# - external_network
# - internal_network
networks:
external_network:
internal_network:
internal: true
随后将.env.production复制到目录下,修改DB_HOST、REDIS_HOST、ES_HOST以跟docker-compose.yml中的设置一致,命名为mastodon_db_1、mastodon_redis_1、mastodon_es_1,mastodon为git clone时设定的文件夹名。
修改完成后运行docker-compose build
安装。
恢复备份
安装完成后运行docker-compose up -d db
运行数据库,将backup.dump复制到目录中并运行cat backup.dump | docker exec -i mastodon_db_1 pg_restore -U mastodon -n public --no-owner --role=mastodon -d mastodon_production
恢复数据库备份。
将备份的/public/system复制到目录下的/public/system。
随后运行docker-compose run --rm web rails db:migrate
迁移数据库,运行docker-compose run --rm web rails assets:precompile
重建assets,运行docker-compose run --rm web bin/tootctl feeds build
重新生成首页,不重新生成首页的话用户登录后首页是空的。
全部完成后用docker-compose up -d
运行所有服务。
配置反代
Apache的反代配置跟nginx有点不一样,网上也没现成的,主要是设置一下根目录,证书更新用的/.well-known/目录,以及反代规则,贴一下我的配置。
<VirtualHost *:443>
SSLEngine on
ServerName mastodon.stsecurity.moe
DocumentRoot /mastodon/public/
SSLCertificateFile /etc/apache2/ssl/mastodoncert.pem
SSLCertificateKeyFile /etc/apache2/ssl/mastodonkey.pem
SSLCertificateChainFile /etc/apache2/ssl/mastodonfullchain.pem
<directory /mastodon/public/.well-known/>
AllowOverride None
Require all granted
</directory>
ErrorLog ${APACHE_LOG_DIR}/mastodon-error.log
CustomLog ${APACHE_LOG_DIR}/mastodon-access.log combined
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
ProxyPass /.well-known !
ProxyPass /500.html !
ProxyPass /oops.png !
ProxyPass /api/v1/streaming/ ws://localhost:4000/
ProxyPassReverse /api/v1/streaming/ ws://localhost:4000/
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
ErrorDocument 500 /500.html
ErrorDocument 501 /500.html
ErrorDocument 502 /500.html
ErrorDocument 503 /500.html
ErrorDocument 504 /500.html
</VirtualHost>
配置完反代再签一下证书,设置一下强制https,就可以正常访问了。
解决ElasticSearch反复重启的问题
服务正常运行后发现ElasticSearch一直在自动重启,本来以为是内存问题,但加了2Gswap后问题依然存在,用docker log mastodon_es_1
查看log发现原因是:
"Caused by: java.nio.file.AccessDeniedException: /usr/share/elasticsearch/data/nodes"
查找了一下解决方案,修改ElasticSearch对应的文件存储地址/mastodon/elasticsearch的权限即可。
运行sudo chown -R 1000:1000 /mastodon/elasticsearch/
或者sudo chmod -R 777 /mastodon/elasticsearch/
即可。
备份数据库
运行docker exec -i mastodon_db_1 pg_dump -Fc mastodon_production -U mastodon -f /var/lib/postgresql/data/backup.dump
即可,文件位于postgres文件夹。
相关链接
Migrate Mastodon from non Docker to Docker
Hosting your own mastodon instance via docker-compose
How to Install Mastodon Using Docker on Alibaba Cloud ECS
本文链接:https://blog.stsecurity.moe/archives/182/
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.