Mastodon là mạng xã hội liên hợp, vì vậy tutorial này dài hơn một container Docker đơn lẻ: cần domain ổn định, PostgreSQL, Redis, secrets, VAPID, streaming, Sidekiq và reverse proxy HTTPS. LOCAL_DOMAIN là giá trị không nên đổi tùy tiện sau khi instance hoạt động.1
Video i12bretro đã được xác thực title/author. Tôi giữ player gốc và không rehost video.2
1. Điều kiện domain và Docker
Host Certbot phải truy cập được từ Internet qua port 80 hoặc 443 để Let's Encrypt xác minh. Với HomeLab, tôi forward port 80 tới host trong thời gian handshake, kiểm tra DNS trỏ đúng và dừng web server đang chiếm port 80.
Cài Docker bằng block source:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# install prerequisitessudo apt install apt-transport-https ca-certificates curl software-properties-common gnupg-agent -y
# add docker gpg keycurl -fsSL https://download.docker.com/linux/$(awk -F'=''/^ID=/{ print $NF }' /etc/os-release)/gpg | sudo apt-key add -
# add docker software repositorysudo add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/$(awk -F'=''/^ID=/{ print $NF }' /etc/os-release)$(lsb_release -cs) stable"# install dockersudo apt install docker-ce docker-compose containerd.io -y
# enable and start docker servicesudo systemctl enable docker && sudo systemctl start docker
# add the current user to the docker groupsudo usermod -aG docker $USER# reauthenticate for the new group membership to take effectsu - $USER
2. Lấy SSL certificate
Loại Certbot apt, cài snapd/core/certbot, tạo symlink, rồi chạy standalone với domain thật:
1
2
3
4
5
6
7
8
9
10
11
12
13
# remove apt version of certbot if installedsudo apt remove certbot -y
# install snapdsudo apt install snapd -y
# install snap core and updatesudo snap install core; sudo snap refresh core
# install certbot snapsudo snap install --classic certbot
# create certbot symbolic linksudo ln -s /snap/bin/certbot /usr/bin/certbot
# if a web server process is currently using port 80, stop it before proceeding# generate a certificatesudo certbot certonly --standalone --preferred-challenges http -d <%DNS NAME%>
Khi được hỏi, nhập email, đồng ý terms và chọn có/không nhận email từ Certbot. Ghi lại vị trí file certificate mà Certbot in ra.
Tạo group để Nginx đọc certificate theo hướng dẫn source:
1
2
3
4
5
6
7
8
9
10
11
# create ssl-certs groupsudo groupadd ssl-certs
# add $USER and root users to groupsudo usermod -aG ssl-certs $USERsudo usermod -aG ssl-certs root
# verify the members of ssl-certgetent group ssl-certs
# set owner group of /etc/letsencryptsudo chgrp -R ssl-certs /etc/letsencrypt
# set permissions on /etc/letsencryptsudo chmod -R g=rX /etc/letsencrypt
3. Chuẩn bị Mastodon và .env
Tạo thư mục PostgreSQL, Redis, public system và Nginx; pull image, chạy rake secret hai lần, chạy lệnh tạo VAPID key rồi mở .env:
1
2
3
4
5
6
7
8
9
10
11
12
# create working directoriesmkdir ~/docker/postgres -p && mkdir ~/docker/redis -p && mkdir ~/docker/mastodon/public/system -p && mkdir ~/docker/nginx/conf -p
# pull the mastodon web containerdocker pull tootsuite/mastodon
# generate secrets, run this 2 timesdocker run --rm -it tootsuite/mastodon bundle exec rake secret
# generate VAPID keysdocker run --rm -it tootsuite/mastodon bundle exec rake mastodon:webpush:generate_vapid_key
# create a mastodon .env file# copy the generated secrets and keys into the .env file# make sure to set the LOCAL_DOMAIN as this cannot be changed laternano ~/docker/mastodon/.env
Dán mẫu .env và sửa LOCAL_DOMAIN, WEB_DOMAIN, PostgreSQL, secret, Web Push và SMTP. Tôi giữ tên biến nhưng không đưa password nguồn vào repo; giá trị DB_PASS, password database và SMTP nếu có phải là secret riêng:1
# This is a sample configuration file. You can generate your configuration# with the `rake mastodon:setup` interactive setup wizard, but to customize# your setup even further, you'll need to edit it manually. This sample does# not demonstrate all available configuration options. Please look at# https://docs.joinmastodon.org/admin/config/ for the full documentation.# Note that this file accepts slightly different syntax depending on whether# you are using `docker-compose` or not. In particular, if you use# `docker-compose`, the value of each declared variable will be taken verbatim,# including surrounding quotes.# See: https://github.com/mastodon/mastodon/issues/16895# Federation# ----------# This identifies your server and cannot be changed safely later# ----------LOCAL_DOMAIN=i12bretro.local# ----------# Optional, if different than LOCAL_DOMAIN# ----------#WEB_DOMAIN=toots.webredirect.org# Redis# -----REDIS_HOST=redisREDIS_PORT=6379# PostgreSQL# ----------DB_HOST=postgresDB_USER=mastodon_rwDB_NAME=mastodonDB_PASS=[REDACTED]DB_PORT=5432# Secrets# -------# Make sure to use `rake secret` to generate secrets# -------SECRET_KEY_BASE=OTP_SECRET=# Web Push# --------# Generate with `rake mastodon:webpush:generate_vapid_key`# --------VAPID_PRIVATE_KEY=VAPID_PUBLIC_KEY=# Sending mail# ------------SMTP_SERVER=smtp.example.comSMTP_PORT=25SMTP_LOGIN=SMTP_PASSWORD=SMTP_FROM_ADDRESS=mastodon@example.com# IP and session retention# -----------------------# Make sure to modify the scheduling of ip_cleanup_scheduler in config/sidekiq.yml# to be less than daily if you lower IP_RETENTION_PERIOD below two days (172800).# -----------------------IP_RETENTION_PERIOD=31556952SESSION_RETENTION_PERIOD=31556952
Nhấn CTRL+O, Enter, CTRL+X để lưu .env. Tài liệu cấu hình đầy đủ của Mastodon là nguồn bổ sung được i12bretro liên kết; tôi không coi sample rút gọn là đầy đủ cho production.
4. Chạy PostgreSQL, Redis và Mastodon
Chạy network, database, migration, frontend, tạo owner/admin, rồi khởi động streaming và Sidekiq. Ở lệnh tạo account, thay placeholder username/email và lưu password output an toàn; không ghi password vào Markdown:1
# set owner of docker directorysudo chown "$USER":"$USER" ~/docker -R
# create containersdocker network create containers
# run the postgesql container# Replace the source password value with your own local secret before running.docker run -d --name postgres -e POSTGRES_USER=mastodon_rw -e POSTGRES_PASSWORD=[REDACTED] -e POSTGRES_DB=mastodon -v ~/docker/postgres:/var/lib/postgresql/data --network containers --restart=unless-stopped postgres:latest
# run the redis containerdocker run -d --name redis -v ~/docker/redis:/data --network containers --restart=unless-stopped redis
# initialize the mastodon databasedocker run --rm -it --network containers --env-file ~/docker/mastodon/.env tootsuite/mastodon rails db:migrate
# run the mastodon frontend containerdocker run -d --name mastodon --env-file ~/docker/mastodon/.env -p 3000:3000 -v ~/docker/mastodon/public/system:/mastodon/public/system --network containers --restart=unless-stopped tootsuite/mastodon bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"# connect to shell inside mastodon containerdocker exec -it mastodon /bin/bash
# set the RAILS_ENV variableRAILS_ENV=production
# create an owner/admin account# copy the password output for laterbin/tootctl accounts create <%username%> --email <%email address%> --confirmed --role Owner
# exit the containerexit# run the mastodon streaming containerdocker run -d --name mastodon-stream --env-file ~/docker/mastodon/.env -p 4000:4000 --network containers --restart=unless-stopped tootsuite/mastodon node ./streaming
# run the mastodon sidekiq containerdocker run -d --name mastodon-sidekiq --env-file ~/docker/mastodon/.env --network containers -v ~/docker/mastodon/public/system:/mastodon/public/system --restart=unless-stopped tootsuite/mastodon bundle exec sidekiq
5. Nginx reverse proxy
Tải nginx config chính thức của Mastodon, sửa upstream để chạy qua Docker network, thay domain và đường dẫn certificate, rồi tạo container proxy:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# download the default mastodon nginx configurationwget -O ~/docker/nginx/conf/mastodon.conf https://raw.githubusercontent.com/mastodon/mastodon/main/dist/nginx.conf
# replace some options to work running in docker containerssed -i "s/try_files \$uri =404;/try_files \$uri @proxy;/" ~/docker/nginx/conf/mastodon.conf
# update the server_name with the URL being used to reach mastodon# make sure to replace WEB_DOMAINsed -i "s/server_name example.com;/\server_name <%WEB_DOMAIN%>;/" ~/docker/nginx/conf/mastodon.conf
# update mastodon frontend serversed -i 's/server 127.0.0.1:3000/server mastodon:3000/' ~/docker/nginx/conf/mastodon.conf
# update mastodon stream serversed -i 's/server 127.0.0.1:4000/server mastodon-stream:4000/' ~/docker/nginx/conf/mastodon.conf
# update the ssl certificate path# make sure to replace DNS NAMEsed -i 's/# ssl_certificate\s*\/etc\/letsencrypt\/live\/example.com\/fullchain.pem;/ssl_certificate\t\/etc\/letsencrypt\/live\/<%DNS NAME%>\/fullchain.pem;/' ~/docker/nginx/conf/mastodon.conf
# update the ssl key path# make sure to replace DNS NAMEsed -i 's/# ssl_certificate_key\s*\/etc\/letsencrypt\/live\/example.com\/privkey.pem;/ssl_certificate_key\t\/etc\/letsencrypt\/live\/<%DNS NAME%>\/privkey.pem;/' ~/docker/nginx/conf/mastodon.conf
# create nginx proxy containerdocker run --name nginx -p 80:80 -p 443:443 --network containers -v ~/docker/nginx/conf:/etc/nginx/conf.d:ro -v /etc/letsencrypt:/etc/letsencrypt:ro -d nginx
Đọc lại mastodon.conf sau mỗi sed; các placeholder <%WEB_DOMAIN%> và <%DNS NAME%> phải được thay bằng domain thật trước khi chạy. Kiểm tra port 80/443 chỉ có proxy cần thiết đang listen.
6. Đăng nhập và đổi password
Mở https://<%WEB_DOMAIN%>, bấm Sign in và dùng owner email/password đã tạo. Vào Preferences → Account, nhập password hiện tại, đặt và xác nhận password mới, bấm Save Changes, Logout rồi login lại để xác nhận.
Kiểm tra sau triển khai
Kiểm tra docker ps, log từng container, certificate chain, HTTPS redirect, PostgreSQL/Redis health, streaming và Sidekiq. Backup ~/docker/mastodon, .env ngoài repo với quyền chặt; không public trực tiếp cổng 3000/4000 và không đưa .env vào Git.
Góp Ý / Bình Luận / Đánh giá